关于Shell脚本中set -e与test命令行为不符预期的疑问
拆解
set -e与test结合的行为差异 这问题其实是踩中了set -e一个容易被忽略的规则细节,我来给你掰扯清楚:
首先得明确set -e的核心逻辑:它会在单个命令返回非零退出码时立刻终止脚本,但有个关键例外——如果返回非零的命令是&&/||链式命令中的「非最后一个命令」,set -e不会触发终止。
分析你的两种测试场景
场景1:启用test $a -gt $b && false(a=10,b=9,即a>b)
test $a -gt $b判断为真,退出码是0,所以会执行&&后面的false;false的退出码是非零,而且它是整个&&链的最后一个命令,完全符合set -e的终止条件,脚本直接停在这里,后续的echo "111"根本没机会运行,所以你看不到任何输出。
场景2:启用test $a -lt $b && false(a=10,b=9,即a>b)
test $a -lt $b判断为假,退出码是非零,&&会触发短路逻辑,后面的false不会执行;- 这里返回非零的是
&&链中的第一个命令,不属于「链的最后一个命令」,所以set -e不会触发终止,脚本继续往下走,echo "111"正常执行,就输出了内容。
实现你预期的「无论哪种情况都终止脚本」
如果想让脚本不管test的结果如何,都终止运行不输出111,可以这么改:
#!/bin/bash set -e a=10 b=9 # 方案1:把test和false拆成独立命令,让test的非零退出码直接触发set -e test $a -lt $b false # 方案2:用if包裹,主动触发终止 # if test $a -lt $b; then # exit 1 # else # exit 1 # fi echo "111"
这样不管test返回0还是非零,要么test直接触发set -e终止,要么false执行后触发终止,echo永远不会运行。
内容的提问来源于stack exchange,提问作者Jack Dai
相关产品推荐
相关产品推荐

