Linux Mint下Bash脚本无法启动Make构建的可执行文件问题排查
问题原因分析
你遇到的这个问题,核心是Linux分支的build任务里的cd命令改变了脚本的当前工作目录,导致后续run任务执行时的相对路径完全出错了。
咱们具体拆解一下:
- 当你执行
./script.sh build run时,整个脚本是在同一个进程里依次执行build和run任务的。 - 在Linux的
build分支中,你写了cd ./build/debug/ && make——这个cd是直接在脚本的当前进程里生效的,等make执行完,脚本的工作目录已经变成了./build/debug/。 - 接下来执行
run任务时,你用的相对路径./build/debug/program,就会变成从./build/debug/这个目录出发去找./build/debug/program,实际对应的绝对路径是/你的项目路径/build/debug/build/debug/program,这显然不存在,所以才会报错“no such file or directory”。
那为什么分开执行就没问题?
- 执行
./script.sh build && ./script.sh run时,两个script.sh是完全独立的进程:第一个进程执行build后,它的工作目录改变不会影响第二个新启动的进程,第二个进程的工作目录还是项目根目录,所以./build/debug/program的路径是正确的。 - 手动执行
./build/debug/program也是在项目根目录下操作,路径自然不会错。
至于Cygwin下正常运行,是因为Windows分支的build任务没有执行cd操作,脚本全程都在项目根目录,run任务的路径从始至终都是正确的。
修复方案
有两种简单可靠的修复方式,任选其一即可:
方案1:用子shell执行cd + make,不影响脚本全局工作目录
把Linux分支的build代码改成这样:
elif [[ $OS == 'Linux' ]]; then # 用括号包裹命令,在子shell里执行cd和make,不会改变脚本主进程的工作目录 (cd ./build/debug/ && make) fi
子shell里的cd只会改变子进程的工作目录,脚本主进程的工作目录依然保持在项目根目录,后续run任务的路径就不会出错了。
方案2:执行完make后切回原工作目录
先保存当前的工作目录,等make执行完成后再切回去:
elif [[ $OS == 'Linux' ]]; then # 保存脚本当前的工作目录 original_dir=$(pwd) cd ./build/debug/ && make # 切回原来的工作目录 cd "$original_dir" fi
这种方式也能保证后续run任务的工作目录始终是项目根目录。
额外优化建议
为了彻底避免类似的路径问题,你可以在脚本开头定义项目根目录的绝对路径,后续所有操作都基于这个绝对路径来写,比如:
# 脚本开头定义项目根目录(假设脚本放在项目根目录下) PROJECT_ROOT=$(cd "$(dirname "$0")" && pwd) # 然后把run阶段改成绝对路径调用 elif [[ $OS == 'Linux' ]]; then "$PROJECT_ROOT/build/debug/program" fi
这样不管脚本的工作目录怎么变化,路径都是绝对准确的,脚本的健壮性会更高。
内容的提问来源于stack exchange,提问作者Lukas-T
相关产品推荐
相关产品推荐

