Tôi giả sử bạn vẫn muốn thấy STDERR và STDOUT trên thiết bị đầu cuối. Bạn có thể tìm câu trả lời của Josh Kelley, nhưng tôi thấy việc giữ tail
xung quanh trong nền tạo ra tệp nhật ký của bạn rất hack và lộn xộn. Lưu ý cách bạn cần giữ exra FD và dọn dẹp sau đó bằng cách giết nó và về mặt kỹ thuật nên thực hiện điều đó trong một trap '...' EXIT
.
Có một cách tốt hơn để làm điều này và bạn đã phát hiện ra nó : tee
.
Chỉ, thay vì chỉ sử dụng nó cho thiết bị xuất chuẩn của bạn, hãy có một tee cho thiết bị xuất chuẩn và một cho thiết bị xuất chuẩn. Làm thế nào bạn sẽ thực hiện điều này? Thay thế quá trình và chuyển hướng tập tin:
command > >(tee -a stdout.log) 2> >(tee -a stderr.log >&2)
Hãy chia nó ra và giải thích:
> >(..)
>(...)
(thay thế quá trình) tạo ra một bộ xếp hình và cho phép tee
lắng nghe nó. Sau đó, nó sử dụng >
(chuyển hướng tập tin) để chuyển hướng STDOUT của command
tới FIFO mà lần đầu tiên bạn tee
đang nghe.
Điều tương tự cho lần thứ hai:
2> >(tee -a stderr.log >&2)
Chúng tôi sử dụng thay thế quy trình một lần nữa để tạo ra một tee
quy trình đọc từ STDIN và đưa nó vào stderr.log
. tee
xuất lại đầu vào của nó trên STDOUT, nhưng vì đầu vào của nó là STDERR của chúng tôi, chúng tôi muốn chuyển hướng tee
STDOUT sang STDERR của chúng tôi một lần nữa. Sau đó, chúng tôi sử dụng chuyển hướng tệp để chuyển hướng command
STDERR sang đầu vào của FIFO ( tee
STDIN).
Xem http://mywiki.wooledge.org/BashGuide/InputAndOutput
Thay thế quy trình là một trong những điều thực sự đáng yêu mà bạn nhận được như một phần thưởng khi chọn bash
làm vỏ của mình chứ không phải là sh
(POSIX hoặc Bourne).
Trong sh
, bạn phải làm mọi thứ bằng tay:
out="${TMPDIR:-/tmp}/out.$$" err="${TMPDIR:-/tmp}/err.$$"
mkfifo "$out" "$err"
trap 'rm "$out" "$err"' EXIT
tee -a stdout.log < "$out" &
tee -a stderr.log < "$err" >&2 &
command >"$out" 2>"$err"