如http://mywiki.wooledge.org/BashFAQ/106 中所述,您可以对所有命令应用全局重定向。
所以你可以像这样开始你的脚本:
exec 3>&1 >log 2>&1
使用此命令,新的 fd 3 将被分配给 screen,已存在的 fd1 将被发送到日志文件,stderr 也将被发送到日志文件。
试一试(或查看我的测试here)
exec 3>&1 >log 2>&1
ls nofile #This will raise an error on stderr
echo "hello" #This would normally be printed on stdout / fd1
echo "hello again" >&3 #This will go in fd3
#Output:
hello again
$ cat log
ls: cannot access nofile: No such file or directory
hello
ls 将失败(除非您有一个名为“nofile”的文件:))但错误消息将发送到 log gile。
echo 将成功打印 "hello" ,但这将转到 fd1 ,这意味着再次记录到日志文件。
最后一个回显被重定向到 fd3 = 你的真实屏幕,这是你在现实中看到的唯一消息。
向前迈出一步,您可以使用 $? 捕获每个命令的结果? (如果要使用管道,则使用 bash PIPESTATUS 数组)。
另一个测试:
exec 3>&1 >log 2>&1
ls nofile; ex=$?;
[[ "$ex" -ne 0 ]] && (echo "Oops, something gone wrong.Exit status = $ex" && cat log) >&3
#Output
Oops, something gone wrong.Exit status = 2
ls: cannot access nofile: No such file or directory
另一种方式
if ! ls nofile;then echo "something is wrong" >&3;fi
如果 ls 失败,将在您的屏幕上打印“有问题”
如果 ls 没有失败,将打印它的结果以进行日志记录,并且您在屏幕上什么也看不到。
一般来说,使用这种方法,您可以始终将 stderr 和 stdout 重定向到一个文件,并且您可以通过在要打印结果的每个命令中应用 >&3 来选择性地在屏幕上打印消息你的屏幕。
我不知道是否可以根据每个命令的退出状态进行自动重定向。这就是 stderr 的用途。打印错误。
看来每条命令执行完后都需要监控其退出状态。
另外,请注意,根据执行的操作(即命令差异),某些命令可能返回不同于零的退出状态