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

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

/ 猿问

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

沧海一幻觉 2019-12-07 15:05:45

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



查看完整描述

3 回答

?
largeQ

在每个命令之后,都可以在$?变量中找到退出代码,因此您将获得以下内容:


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
?
墨色风雨

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


另一种方法是这样做:


set -e

set -o pipefail

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


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


查看完整回答
反对 回复 2019-12-07
?
LEATH

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


如何获得cmd1in 的退出代码cmd1|cmd2


首先,请注意,cmd1退出代码可以为非零值,但仍然并不意味着错误。例如发生在


cmd | head -1

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


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


一种。使用zsh:


退出代码在pipestatus特殊数组中提供。 cmd1输入退出代码$pipestatus[1],输入cmd3退出代码 $pipestatus[3],因此$?总是与 $pipestatus[-1]。


b。用bash:


退出代码在PIPESTATUS特殊数组中提供。 cmd1输入退出代码${PIPESTATUS[0]},输入cmd3退出代码 ${PIPESTATUS[2]},因此$?总是与 ${PIPESTATUS: -1}。


...

查看完整回答
反对 回复 2019-12-07
  • 3 回答
  • 0 关注
  • 68 浏览
我要回答

添加回答

回复

举报

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