为了账号安全,请及时绑定邮箱和手机立即绑定

基于进程退出代码的退出Shell脚本

基于进程退出代码的退出Shell脚本

沧海一幻觉 2019-12-07 15:05:45
我有一个执行许多命令的Shell脚本。如果任何命令以非零退出代码退出,如何使shell脚本退出?
查看完整描述

3 回答

?
largeQ

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值,则将其存储在其中。


查看完整回答
反对 回复 2019-12-07
?
墨色风雨

TA贡献1853条经验 获得超6个赞

如果要使用$ ?,则需要在每个命令后进行检查,因为$?每个命令退出后更新。这意味着,如果您执行管道,则只会获取管道中最后一个进程的退出代码。


另一种方法是这样做:


set -e

set -o pipefail

如果将其放在shell脚本的顶部,则bash似乎会为您解决这个问题。如前所述,“ set -e”将导致bash退出并在任何简单命令上出现错误。“ set -o pipefail”也将导致bash退出,并且管道中的任何命令也会出错。


有关此问题的更多讨论,请参见此处或此处。 这是内置的bash手册部分。


查看完整回答
反对 回复 2019-12-07
  • 3 回答
  • 0 关注
  • 706 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信