Gửi đầu ra bash -x đến logfile mà không xen vào đầu ra tiêu chuẩn


12

Có cách nào để gửi thông tin được hiển thị bằng cách chạy tập lệnh bash với tùy chọn -x đến một tệp, trong khi không thay đổi đầu ra tiêu chuẩn mà người dùng đang chạy tập lệnh nhìn thấy?

Đây là một tính năng sửa lỗi tôi muốn triển khai trong tập lệnh bash mà chúng tôi sử dụng thường xuyên thay đổi.

Nhiều đánh giá cao.

Câu trả lời:


21

Đầu ra từ -x đi đến stderr, không phải stdout. Nhưng thậm chí đó có thể là một vấn đề - rất nhiều tập lệnh sẽ có các phụ thuộc chức năng vào nội dung của stderr, và loại lộn xộn của nó có các luồng gỡ lỗi và stderr trộn lẫn với nhau trong một số trường hợp.

Các phiên bản Bash> 4.1 cung cấp một giải pháp khác: biến môi trường BASH_XTRACEFD cho phép bạn chỉ định một bộ mô tả tệp sẽ được sử dụng để gửi luồng gỡ lỗi tới. Đây có thể là một tập tin hoặc đường ống hoặc bất kỳ lòng tốt unix-y nào bạn muốn.

# Use FD 19 to capture the debug stream caused by "set -x":
exec 19>/tmp/my-script.log
# Tell bash about it  (there's nothing special about 19, its arbitrary)
export BASH_XTRACEFD=19

# turn on the debug stream:
set -x

# run some commands:
cd /etc
find 
echo "Well, that was fun."

# Close the output:
set +x
exec 19>&-

# See what we got:
cat /tmp/my-script.log

Với một chút khó khăn hơn, bạn có thể làm những việc khác - như thực hiện một 'tee' trên các luồng stdout và / hoặc stdin, và xen kẽ những thứ đó với đầu ra gỡ lỗi, để nhật ký của bạn hoàn thiện hơn. Để biết thêm chi tiết về điều này, hãy xem /programming/3173131/redirect-copy-of-stdout-to-log-file-from-within-bash-script-itself .

Ưu điểm lớn của phương pháp này so với các lựa chọn thay thế là bạn không mạo hiểm thay đổi hành vi của tập lệnh của mình bằng cách đưa đầu ra gỡ lỗi vào thiết bị xuất chuẩn hoặc thiết bị xuất chuẩn.


Xem thêm ở đây về cách tìm một mô tả tệp không sử dụng cho tệp.
jarno

Có nhất thiết phải đóng bộ mô tả tập tin (tức là dòng exec 19>&-) không? Theo kinh nghiệm của tôi, nó được đóng tự động, khi kịch bản kết thúc.
jarno

1
Đoạn mã hiển thị ở trên không cho rằng bạn đang chạy tập lệnh hoặc tập lệnh có thể kéo dài bao lâu, v.v ... Đúng là nếu bạn chỉ làm những gì đoạn trích này đang làm và đặt nó vào tập lệnh, bộ xử lý tệp sẽ bị đóng chỉ vì toàn bộ phần vỏ biến mất ở phần cuối của tập lệnh. Vì vậy, trong trường hợp sử dụng đó, bạn không cần phải đóng tay cầm. Nhưng nói chung khi mã hóa dựa vào tài nguyên, cách tốt nhất là đóng những gì bạn đã mở, bởi vì sau đó mã của bạn có thể được sử dụng trong bối cảnh lớn hơn, nơi việc dọn phòng có nhiều vấn đề hơn.
Stablesog

Tại sao bạn xuất BASH_XTRACEFD? Tại sao không chỉ đặt giá trị cho nó?
jarno

Dù sao, một cách khác để đóng bộ mô tả tệp là đặt giá trị mới (ví dụ null) cho BASH_XTRACEFD hoặc bỏ đặt nó.
jarno

4

set -xkhông gửi bất cứ điều gì đến đầu ra tiêu chuẩn, vì vậy không có vấn đề ở đó. Những gì nó không làm là ghi vào sai số chuẩn, mà đi đến giao diện điều khiển theo mặc định.

Những gì bạn muốn làm là chuyển hướng thiết bị xuất chuẩn sang tệp khác, như thế này:

/bin/sh -x /my/script/file 2>/my/log/file

1

Xem man tee.

Bạn chạy nó như thế nào tee commandname filenamevà nó sẽ hiển thị đầu ra lệnh stdoutvà viết nó vào filename.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.