Codefresh中Shell for循环语法错误排查求助
Codefresh Freestyle步骤Shell循环语法错误排查与解决
问题1:数组定义触发/bin/sh: syntax error: bad substitution
错误代码
steps: arti_lib_deploy: stage: build image type: freestyle title: "Deploy Libs to Artifactory" image: 'hub.artifactory.gcp.xxxx/curlimages/curl:latest' commands: - LIB_FOLDERS=["lib1","lib2"] - > for LIB_FOLDER in "${LIB_FOLDERS[@]}"; do echo "FolderName- ${LIB_FOLDER}" curl -X GET -kv https://xxxx.service.test/entitlements/effPermissions?permissionId= "${LIB_FOLDER}" done
错误日志
Executing command: LIB_FOLDERS=["lib1","lib2"] [2023-08-06T10:54:14.700Z] ------------------------------ Executing command: for LIB_FOLDER in "${LIB_FOLDERS[@]}"; do echo "FolderName-${LIB_FOLDER }" done [2023-08-06T10:54:14.701Z] /bin/sh: syntax error: bad substitution ...
原因
- Codefresh Freestyle步骤默认使用
/bin/sh执行命令,而sh不支持Bash专属的数组展开语法${LIB_FOLDERS[@]}。 - 数组定义写法不符合规范,正确的Bash数组定义应为
LIB_FOLDERS=("lib1" "lib2")(元素间用空格分隔,无逗号)。
问题2:空格分隔字符串触发/bin/sh: syntax error: unexpected end of file (expecting "done")
错误代码
commands: - LIB_FOLDERS="lib1 lib2" - for LIB_FOLDER in $LIB_FOLDERS; do echo "FolderName- $LIB_FOLDER" done
错误日志
Executing command: LIB_FOLDERS="lib1 lib2" ------------------------------ /bin/sh: syntax error: unexpected end of file (expecting "done") ...
原因
Codefresh的commands列表中每一项都是独立执行的命令。拆分后的for循环第一行for LIB_FOLDER in $LIB_FOLDERS;会被sh判定为不完整命令,后续的do和done属于单独命令行,无法形成闭合的循环结构,因此报错。
修复方案
方案1:使用sh兼容的单命令循环(推荐)
将变量定义和循环逻辑合并为一个完整的Shell命令,用>保持格式可读性:
steps: arti_lib_deploy: stage: build image type: freestyle title: "Deploy Libs to Artifactory" image: 'hub.artifactory.gcp.xxxx/curlimages/curl:latest' commands: - > LIB_FOLDERS="lib1 lib2" && for LIB_FOLDER in $LIB_FOLDERS; do echo "FolderName- ${LIB_FOLDER}" curl -X GET -kv "https://xxxx.service.test/entitlements/effPermissions?permissionId=${LIB_FOLDER}" done
注意:curl的URL需将变量嵌入引号内,避免空格或特殊字符引发参数拆分问题。
方案2:指定使用Bash执行
若需使用Bash数组特性,可通过bash -c包裹脚本内容:
steps: arti_lib_deploy: stage: build image type: freestyle title: "Deploy Libs to Artifactory" image: 'hub.artifactory.gcp.xxxx/curlimages/curl:latest' commands: - > bash -c ' LIB_FOLDERS=("lib1" "lib2") for LIB_FOLDER in "${LIB_FOLDERS[@]}"; do echo "FolderName- ${LIB_FOLDER}" curl -X GET -kv "https://xxxx.service.test/entitlements/effPermissions?permissionId=${LIB_FOLDER}" done '
注意:使用bash -c时,内部脚本需用单引号包裹,避免YAML与Shell的变量解析冲突。
内容的提问来源于stack exchange,提问作者Shabar
相关产品推荐
相关产品推荐

