我有一个执行许多命令的shell脚本。 若是任何命令以非零退出代码退出,如何使shell脚本退出? html
http://cfaj.freeshell.org/shell/cus-faq-2.html#11 shell
如何在cmd1|cmd2
获取cmd1
的退出代码 数组
首先,请注意cmd1
退出代码可能不为零,但仍然不表明错误。 例如,这发生在 bash
cmd | head -1
您可能会观察到cmd1
的141(或269与ksh93)退出状态,但这是由于当读取一行后头head -1
终止时, cmd
被SIGPIPE信号中断。 spa
要知道管道元素cmd1 | cmd2 | cmd3
的退出状态 cmd1 | cmd2 | cmd3
code
一个。 用zsh: htm
退出代码在pipestatus特殊数组中提供。 cmd1
退出代码在$pipestatus[1]
, cmd3
退出代码在$pipestatus[3]
,这样$?
始终与$pipestatus[-1]
。 ip
湾 用bash: get
退出代码在PIPESTATUS
特殊阵列中提供。 cmd1
退出代码在${PIPESTATUS[0]}
, cmd3
退出代码在${PIPESTATUS[2]}
,因此$?
老是与${PIPESTATUS: -1}
。 cmd
...
有关详细信息,请参阅如下连接 。
[ $? -eq 0 ] || exit $?; # exit for none-zero return code
在bash中这很容易,只需用&&将它们绑在一块儿:
command1 && command2 && command3
您还可使用嵌套的if结构:
if command1 then if command2 then do_something else exit fi else exit fi
在每一个命令以后,能够在$?
找到退出代码$?
变量,因此你会有这样的东西:
ls -al file.ext rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
你须要当心管道命令,由于$?
只提供管道中最后一个元素的返回码,所以,在代码中:
ls -al file.ext | sed 's/^/xx: /"
若是文件不存在,则不会返回错误代码(由于管道的sed
部分实际工做,返回0)。
bash
shell实际上提供了一个能够帮助处理PIPESTATUS
。 此数组为每一个管道组件都有一个元素,您能够像${PIPESTATUS[0]}
同样单独访问:
pax> false | true ; echo ${PIPESTATUS[0]} 1
请注意,这会使您得到false
命令的结果,而不是整个管道。 您还能够根据须要获取整个列表进行处理:
pax> false | true | false; echo ${PIPESTATUS[*]} 1 0 1
若是您想从管道中获取最大的错误代码,可使用如下内容:
true | true | false | true | false rcs=${PIPESTATUS[*]}; rc=0; for i in ${rcs}; do rc=$(($i > $rc ? $i : $rc)); done echo $rc
这依次遍历每一个PIPESTATUS
元素,若是它大于前一个rc
值,则将其存储在rc
。
“ set -e
”多是最简单的方法。 只需将它放在程序中的任何命令以前。