是否存在简单的单行方式,或简单的函数,例如bash命令:
动机:travis-ci对总log cout / cerr大小有4MB的限制。这会在超出构建时终止构建,因此我只想打印实际错误,但是当检测到错误时,travis也会终止,就像set -e
一样。
答案 0 :(得分:1)
我认为你需要的是:
ls real_file.txt > /tmp/out.txt 2>&1 || echo $? && cat /tmp/out.txt
ls non_existent.txt > /tmp/out.txt 2>&1 || echo $? && cat /tmp/out.txt
补充:在OP的反馈之后:
ls real_file.txt > /tmp/out.txt 2>&1 || (echo $? && cat /tmp/out.txt)
ls non_existent.txt > /tmp/out.txt 2>&1 || (echo $? && cat /tmp/out.txt)
答案 1 :(得分:0)
正如http://mywiki.wooledge.org/BashFAQ/106中所述,您可以为所有命令应用全局重定向。
所以你可以像这样开始你的脚本:
exec 3>&1 >log 2>&1
使用此命令,将新的fd 3分配给屏幕,现有的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的用途。打印错误。
您似乎需要在执行后监视每个命令的退出状态。
另外,请注意某些命令可能会根据执行的操作(即命令差异)返回不同于零的退出状态