3 回答

TA贡献2039条经验 获得超7个赞
在每个命令之后,都可以在$?变量中找到退出代码,因此您将获得以下内容:
ls -al file.ext
rc=$?; if [[ $rc != 0 ]]; then exit $rc; fi
您需要注意管道命令,因为$?唯一命令会为您提供管道中最后一个元素的返回代码,因此,在代码中:
ls -al file.ext | sed 's/^/xx: /"
如果文件不存在,则不会返回错误代码(因为sed管道的一部分实际起作用,返回0)。
该bash壳实际上提供一种阵列,其可以协助在这种情况下,即是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值,则将其存储在其中。

TA贡献1853条经验 获得超6个赞
如果要使用$ ?,则需要在每个命令后进行检查,因为$?每个命令退出后更新。这意味着,如果您执行管道,则只会获取管道中最后一个进程的退出代码。
另一种方法是这样做:
set -e
set -o pipefail
如果将其放在shell脚本的顶部,则bash似乎会为您解决这个问题。如前所述,“ set -e”将导致bash退出并在任何简单命令上出现错误。“ set -o pipefail”也将导致bash退出,并且管道中的任何命令也会出错。
有关此问题的更多讨论,请参见此处或此处。 这是内置的bash手册部分。
添加回答
举报