Câu trả lời được chấp nhận không bảo tồn STDERR như một mô tả tệp riêng biệt. Điều đó có nghĩa là
./script.sh >/dev/null
sẽ không xuất ra bar
terminal, chỉ tới logfile và
./script.sh 2>/dev/null
sẽ xuất cả hai foo
và bar
đến thiết bị đầu cuối. Rõ ràng đó không phải là hành vi mà một người dùng bình thường có thể mong đợi. Điều này có thể được khắc phục bằng cách sử dụng hai quy trình tee riêng biệt cả hai nối vào cùng một tệp nhật ký:
#!/bin/bash
# See (and upvote) the comment by JamesThomasMoon1979
# explaining the use of the -i option to tee.
exec > >(tee -ia foo.log)
exec 2> >(tee -ia foo.log >&2)
echo "foo"
echo "bar" >&2
(Lưu ý rằng ban đầu không cắt bớt tệp nhật ký - nếu bạn muốn hành vi đó bạn nên thêm
>foo.log
lên đầu tập lệnh.)
Đặc tả POSIX.1-2008tee(1)
yêu cầu đầu ra không có bộ đệm, tức là không được đệm dòng, do đó, trong trường hợp này, có thể STDOUT và STDERR có thể kết thúc trên cùng một dòng foo.log
; tuy nhiên điều đó cũng có thể xảy ra trên thiết bị đầu cuối, vì vậy tệp nhật ký sẽ là một sự phản ánh trung thực của những gì có thể nhìn thấy trên thiết bị đầu cuối, nếu không phải là một tấm gương chính xác của nó. Nếu bạn muốn các dòng STDOUT được phân tách rõ ràng khỏi các dòng STDERR, hãy xem xét sử dụng hai tệp nhật ký, có thể có tiền tố tem ngày trên mỗi dòng để cho phép sắp xếp lại theo thời gian sau này.