将 bash stdout+stderr 重定向到一个文件,将 stderr 重定向到另一个文件

将 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.

答案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(尽管您丢失了. zshhas it in的退出状态$pipestatus[1],但bashin 中"${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,zshksh93:

{ 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-cmdtee失败,将报告失败,但确切的数字可能会丢失。

相关内容