/bin/sh在if语句中未找到命令返回0是否符合预期?
关于/bin/sh在if语句中未找到命令时返回0的行为是否符合预期
首先直接给出结论:这种行为完全符合POSIX标准中/bin/sh的预期逻辑,核心原因和set -e的生效规则、shell对条件判断结构的特殊处理有关,下面详细拆解:
1. set -e的生效范围存在例外
set -e的作用是让脚本在**简单命令执行失败(退出码非零)**时立即终止,但POSIX标准明确划定了几种例外场景,其中就包括:
- 命令作为
if、while、until的条件判断部分时,即使命令退出非零,set -e也不会触发脚本终止。
这是因为这类条件结构的核心逻辑就是依赖命令的退出码做分支判断——如果只要条件命令失败就终止脚本,那if的“按需执行分支”功能就完全失去意义了。
2. 未知命令的退出码与脚本最终返回值的关系
当你在if里执行unknown_command时:
- 首先,shell找不到该命令,会返回127的退出码(这是POSIX定义的“命令未找到”标准退出码)。
- 但
if语句的退出码由条件命令的结果决定:条件命令退出非零,if整体退出码为1;条件命令退出零,if整体退出码为0。 - 由于
set -e在if条件中不生效,脚本不会终止,会继续执行后续代码。如果后续代码没有产生非零退出的命令(比如最后执行了echo这类必然成功的命令),脚本最终的退出码就会是0——这应该就是你看到“返回值r为0”的原因。
3. 实际验证示例
比如你有这样的脚本:
set -e if unknown_command; then echo "command succeeded" fi echo "script finished"
执行后会输出:
./test.sh: line 2: unknown_command: command not found script finished
脚本最终的退出码是0,这完全符合预期——因为set -e没有触发终止,最后一行echo执行成功,所以脚本整体返回0。
如果想要让set -e在这种场景下生效,你可以把命令移出if条件,或者手动检查退出码:
set -e unknown_command # 这里会触发set -e,脚本立即终止,退出码127 if [ $? -eq 0 ]; then echo "command succeeded" fi
内容的提问来源于stack exchange,提问作者Alexis Wilke
相关产品推荐
相关产品推荐

