我需要将所有输出重定向到一个文件,此外还将 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
.
答案1
具有zsh
(且zsh
仅)及其multios
特征:
your-cmd 2> stdout+stderr.log >&2 2> stderr.log
由于 fd 2 被重定向两次,zsh
因此实现了内部tee
将其发送到两个文件。
使用bash
(或任何类似 Bourne 的 shell(除了zsh
需要禁用multios
它才能在这里工作的地方)),您可以tee
使用以下命令手动执行 ing:
{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1
your-cmd
(尽管您丢失了. zsh
has it in的退出状态$pipestatus[1]
,但bash
in 中"${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
失败,将报告失败,但确切的数字可能会丢失。