为何脚本中cd到存在目录返回状态码1?直接执行却正常?
问题:明明目录存在,脚本中
cd bundler却返回状态码1? 脚本内容
#!/bin/bash -l source ~/.bashrc set -e echo "1. Current dir" pwd echo "2. Listing in path ..." ls echo "3. Entering dir" cd bundler echo "4. Entered"
执行日志
go@ci-ubuntu-agent-1:/var/lib/go-agent/pipelines/x/src$ bash run.sh 1. Current dir /var/lib/go-agent/pipelines/x/src 2. Listing in path ... bundler run.sh 3. Entering dir... go@ci-ubuntu-agent-1:/var/lib/go-agent/pipelines/x/src$ echo $? 1
疑问
明明目录bundler存在,为何脚本中执行cd bundler返回状态码1?直接在命令行执行该命令返回状态码0;移除脚本中的set -e选项后,脚本可正常运行,请问原因是什么?
解答
核心原因是**source ~/.bashrc执行后,你的.bashrc文件里包含了某个返回非0状态码的命令**,而set -e会让脚本在遇到第一个非0退出码的命令时直接终止。
你看到的cd bundler返回码1其实是假象——脚本根本没执行到cd bundler这一步,是之前的source ~/.bashrc里的某个命令已经触发了set -e的终止逻辑,但因为source命令本身的输出没有被显示,你误以为是cd命令出了问题。
验证这个结论的方法:
- 在脚本的
source ~/.bashrc后面添加一行echo "source执行完成,退出码: $?",查看输出的退出码是否为非0 - 临时注释掉
source ~/.bashrc,再运行脚本,会发现cd bundler能正常执行,脚本也能走到echo "4. Entered"这一步
移除set -e后脚本正常运行的原因:set -e的作用是“当脚本中任何命令的退出状态不为0时,立即终止脚本”,去掉它之后,即使.bashrc里有非0返回的命令,脚本也会继续执行后续的cd bundler。
而命令行直接执行cd bundler没问题,是因为命令行环境默认没有开启set -e,且手动执行时的.bashrc加载流程和脚本中source ~/.bashrc的上下文存在差异(比如某些条件判断的环境变量不同,导致.bashrc里的某些命令在脚本中执行时返回非0,命令行中却不会)。
内容的提问来源于stack exchange,提问作者leoOrion
相关产品推荐
相关产品推荐

