Bash
將 bash stdout+stderr 重定向到一個文件,將 stderr 重定向到另一個文件
我需要將所有輸出重定向到一個文件,此外還需要將 stderr 重定向到另一個文件。這可以輕鬆完成嗎?
假設我在本範例中的命令是:
php /tmp/doWork.php
我可以使用以下方法將輸出輸出到單獨的文件:
php /tmp/doWork.php 1> /tmp/stdout_file 2> /tmp/stderr_file
基於此,我嘗試:
php /tmp/doWork.php &> /tmp/stdboth_file 2> /tmp/stderr_file
但這只是將 stdout 和 stderr 放入
/tmp/stdboth_file
並且從未寫入/tmp/stderr_file
.
使用
zsh
(並且zsh
僅)及其multios
功能:your-cmd 2> stdout+stderr.log >&2 2> stderr.log
由於 fd 2 被重定向兩次,因此
zsh
實現了內部tee
以將其發送到兩個文件。使用
bash
(或任何類似 Bourne 的 shell(除了zsh
您需要禁用multios
它才能在此處工作的地方)),您可以tee
手動執行以下操作:{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
(儘管您失去了
your-cmd
.zsh
has it in的退出狀態$pipestatus[1]
,但bash
在其中"${PIPESTATUS[0]}"
(前提是重定向到stderr+stdout.log
沒有失敗))。要記錄 的 pid
your-cmd
,您可以執行以下操作:{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
具有
yash
和它的程序重定向功能:your-cmd > stdout+stderr.log 2>(tee stderr.log)
(但請注意,
yash
不會等待該tee
命令的終止,因此在您執行下一個命令時日誌文件可能尚未完成)。可以通過,和中的程序替換來完成類似的事情(並且具有相同的警告) :
bash``zsh``ksh93
{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log
要在後台執行並獲取 pid:
(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!
與
rc
:{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log
rc
的管道允許指定哪些文件描述符連接到管道。對於其他 shell,它始終是左側命令的 fd 1 和右側命令的 fd 0 (因此與上面的 fd 3 一起移動文件描述符)。如果其中之一或失敗,rc
將報告失敗,但確切的數字可能會失去。your-cmd``tee