Linux Shell中sh -c脚本的PIPESTATUS退出码异常问题及解决
问题分析与解决
为什么sh -c无法得到预期的127退出码?
核心原因是变量展开时机的问题:
- 在
sh -c "./a.sh | tee bb.txt; exit ${PIPESTATUS[0]}"命令中,双引号包裹的${PIPESTATUS[0]}会被调用sh -c的当前shell优先解析,而非sh -c启动的子shell。 - 当前shell的
PIPESTATUS[0]记录的是当前shell最近执行的管道命令状态,和sh -c子shell内的管道状态无关。若之前无失败的管道命令,这个值通常为0,导致子shell最终执行exit 0,所以echo $?得到0。 - 直接执行
./a.sh | tee bb.txt; exit ${PIPESTATUS[0]}时,${PIPESTATUS[0]}在当前shell解析,对应管道中第一个命令./a.sh的退出码127,因此最终得到127。
额外注意:多数系统中sh是dash的软链接,而dash不支持PIPESTATUS数组,只有bash支持该特性,这也是用sh -c时可能出现异常的隐性原因。
如何修改sh -c命令以获取预期的127退出码?
需做两个关键调整:
- 用单引号包裹
sh -c的命令内容,避免当前shell提前解析${PIPESTATUS[0]},让子shell自行处理该变量。 - 改用
bash -c替代sh -c,确保shell支持PIPESTATUS数组。
最终修改后的命令:
bash -c './a.sh | tee bb.txt; exit ${PIPESTATUS[0]}'
执行后再运行echo $?即可得到预期的127退出码。
内容的提问来源于stack exchange,提问作者gfan
相关产品推荐
相关产品推荐

