无法找出合适的标题,我不了解dash / bash中的行为。也就是说,如果命令失败,我使用set -e来挽救,并且命令组处理肯定的结果。
即。一般方案是:
[ ! wantcommand ] || command
表示命令仅在需要时才会执行,失败将自动终止脚本。
可能需要进行一些后处理,在这种情况下我使用它:
[ ! wantcommand ] || { command && postprocess; }
这导致了一些好奇的打击,因为这不会杀死外壳而我无法理解这个原因。我现在必须经历一些shell代码,但是想了解原因。
进行测试:
bash -c 'set -e; { false || false && echo "post" ; }; echo "ec $?"'
或:
bash -c 'set -e; { set -e; false || false && echo "post" ; }; echo "ec $?"'
注意:我不是要求修复,而是主要为什么返回码为1,但shell不会退出
答案 0 :(得分:11)
set -e
仅对未经检查失败保释。
当您分组失败时(使用if
,until
,while
,&&
或||
),会检查该失败。
如果没有以这种方式编写规范,则短路布尔操作无法有效地用于流控制,因为错误的分支总是会导致退出。
引用the specification,重点补充:
当此选项打开时,当任何命令失败时(由于Consequences of Shell Errors中列出的任何原因或返回大于零的退出状态),shell将立即退出,就像执行退出特殊操作一样没有参数的内置实用程序,但有以下例外:
多命令管道中任何单个命令的失败都不会导致shell退出。只考虑管道本身的故障。
在执行
while
,until
,if
或elif
保留字后面的复合列表时,应忽略-e设置使用!
保留字,或除最后一个之外的AND-OR列表的任何命令。- 醇>
如果除了subshell命令之外的复合命令的退出状态是在忽略
-e
时失败的结果,则-e
将不适用于此命令。此要求分别适用于shell环境和每个子shell环境。例如,在:
set -e; (false; echo one) | cat; echo two
false
命令导致子shell退出而不执行echo one
;但是,执行echo two
是因为管道(false; echo one) | cat
的退出状态为零。
请注意,此规范随时间而变化;实现POSIX规范的先前版本的shell可能不完全符合此处引用的版本。
在这里注入一些意见 - 我强烈建议阅读BashFAQ #105并确保在决定使用set -e
之前完全理解其中描述的所有行为,而不是通过以下方式实现显式错误处理:手。 FVUE wiki进一步描述了bash-native模式和POSIX模式中set -e
之间行为的区别,这同样应该被理解。