Shell目录遍历脚本本地运行正常但CircleCI执行报错如何解决?
Shell脚本CircleCI运行报错问题排查与修复
报错根因
三个报错分别对应以下三类问题:
[[: not found报错:[[是Bash独有的条件判断语法,CircleCI默认基础镜像多为Debian/Ubuntu系统,默认sh命令指向Dash,如果你在CircleCI配置中使用sh generate-docs.sh执行脚本,会忽略脚本开头的bash shebang声明,用Dash执行不识别[[语法。cd: can't cd to */报错:当脚本执行的工作目录下没有子目录时,通配符*/不会被展开为空,会保留为字面量字符串*/,尝试cd到不存在的目录触发报错。- 脚本还存在多个隐性bug:
- 变量未加双引号包裹,目录/文件名包含空格时会执行失败
- 原代码第13行引用了不存在的变量
$file,实际遍历变量为$f bash *.sh写法在当前目录有多个.sh文件时,只会执行第一个文件,其余文件会被当作参数传入,不符合预期- 若
cd $d执行失败,后续cd ..会退到当前工作目录的上层,导致后续逻辑完全错乱
修复方案
1. 修正脚本逻辑
#!/usr/bin/env bash # 开启通配符不匹配时返回空,避免字面量保留问题 shopt -s nullglob for d in */ ; do # 目录名加引号,cd失败直接跳过当前循环避免后续路径错误 cd "$d" || continue for f in * ; do if [[ $f == *.sh ]]; then if [[ $d == "test/" ]]; then echo "$d" else # 逐个执行所有sh文件,避免多文件执行异常 for sh_file in *.sh; do bash "$sh_file" done fi else if [[ $f == *.yaml ]]; then # 修正错误的变量名 echo "$f" fi fi done cd .. done
2. 修正CircleCI执行命令
不要使用sh执行脚本,要么给脚本加执行权限后直接运行,要么显式调用bash执行:
# 方式1:加执行权限后直接运行 chmod +x generate-docs.sh ./generate-docs.sh # 方式2:显式指定bash执行 bash generate-docs.sh
内容的提问来源于stack exchange,提问作者Fernando Couto
相关产品推荐
相关产品推荐

