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

白昼怎懂夜的黑 提交于 2020-02-25 16:13:45

我有一个执行许多命令的shell脚本。 如果任何命令以非零退出代码退出,如何使shell脚本退出?


#1楼

http://cfaj.freeshell.org/shell/cus-faq-2.html#11

  1. 如何在cmd1|cmd2获取cmd1的退出代码

    首先,请注意cmd1退出代码可能不为零,但仍然不代表错误。 例如,这发生在

    cmd | head -1

    您可能会观察到cmd1的141(或269与ksh93)退出状态,但这是因为当读取一行后头head -1终止时, cmd被SIGPIPE信号中断。

    要知道管道元素cmd1 | cmd2 | cmd3的退出状态 cmd1 | cmd2 | cmd3

    一个。 用zsh:

    退出代码在pipestatus特殊数组中提供。 cmd1退出代码在$pipestatus[1]cmd3退出代码在$pipestatus[3] ,这样$? 始终与$pipestatus[-1]

    湾 用bash:

    退出代码在PIPESTATUS特殊阵列中提供。 cmd1退出代码在${PIPESTATUS[0]}cmd3退出代码在${PIPESTATUS[2]} ,所以$? 总是与${PIPESTATUS: -1}

    ...

    有关详细信息,请参阅以下链接


#2楼

[ $? -eq 0 ] || exit $?; # exit for none-zero return code

#3楼

在bash中这很容易,只需用&&将它们绑在一起:

command1 && command2 && command3

您还可以使用嵌套的if结构:

if command1
   then
       if command2
           then
               do_something
           else
               exit
       fi
   else
       exit
fi

#4楼

在每个命令之后,可以在$?找到退出代码$? 变量,所以你会有这样的东西:

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


#5楼

set -e ”可能是最简单的方法。 只需将它放在程序中的任何命令之前。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!