Bash脚本中循环遍历后无法向数组bazel_cov_req添加全部元素
问题
编写Bash脚本时,将Git变更的目录路径存入变量后遍历,尝试把包含BUILD.bazel文件的路径添加到数组bazel_cov_req中,但数组仅保留第一个添加的元素,无法完整填充所有匹配路径。
脚本代码:
#!/bin/bash # set -v -e -o pipefail bazel_cov_req=() #declared it here for global access. bazel_coverage_pba() { # bazel_cov_req=() bbf="BUILD.bazel" mr_changed_paths=$(git diff HEAD~1 --name-only | grep -e "src/" | xargs dirname | sort | uniq) # echo $mr_changed_paths for apath in ${mr_changed_paths[@]}; do echo "checking for $apath\n" if [ -f "$apath/$bbf" ]; then echo "$apath is a bazel path" echo "add this path to bazel_coverage_required array" bazel_cov_req+=($apath) echo "array of paths to be bazel covered\n" echo {$bazel_cov_req[@]} else echo -e "\tbazel build not found under $apath so skip in coverage" echo "search a --dir in same path $apath" #code here to find file in pre path. fi done } bazel_coverage_pba
运行输出:
checking for src/test/secrets\n src/test/secrets is a bazel path add this path to bazel_coverage_required array array of paths to be bazel covered\n {src/test/secrets[@]} checking for src/test/team\n src/test/team is a bazel path add this path to bazel_coverage_required array array of paths to be bazel covered\n {src/test/secrets[@]} checking for src/ui/automation\n bazel build not found under src/ui/automation so skip in coverage search a --dir in same path src/ui/automation
解决方案
问题根源
mr_changed_paths不是数组:用=$(...)将命令结果存入普通字符串变量,而非数组。遍历${mr_changed_paths[@]}时,Bash会把整个字符串按空格拆分,若路径含空格会直接出错,且无法正确遍历每个独立目录。- 数组打印语法错误:
echo {$bazel_cov_req[@]}是错误写法,Bash不会解析该语法,导致你看到的始终是固定字符串{src/test/secrets[@]},误以为数组未更新。
修复后的脚本
#!/bin/bash # set -v -e -o pipefail bazel_cov_req=() # 全局数组 bazel_coverage_pba() { bbf="BUILD.bazel" # 将命令输出逐行存入数组,支持带空格的路径 mapfile -t mr_changed_paths < <(git diff HEAD~1 --name-only | grep -e "src/" | xargs dirname | sort | uniq) for apath in "${mr_changed_paths[@]}"; do echo "checking for $apath" if [ -f "$apath/$bbf" ]; then echo "$apath is a bazel path" echo "add this path to bazel_coverage_required array" bazel_cov_req+=("$apath") echo "array of paths to be bazel covered:" echo "${bazel_cov_req[@]}" else echo -e "\tbazel build not found under $apath so skip in coverage" echo "search a --dir in same path $apath" # 此处添加上级目录查找逻辑 fi done } bazel_coverage_pba
关键修复点
- 用
mapfile -t mr_changed_paths < <(...)将命令输出逐行存入数组,确保每个目录是独立的数组元素,兼容带空格的路径。 - 遍历数组时使用
"${mr_changed_paths[@]}",加双引号避免路径被空格拆分。 - 打印数组时使用
"${bazel_cov_req[@]}",正确输出所有数组元素。 - 移除多余的
\n,echo默认换行,如需显式换行可使用echo -e。
内容的提问来源于stack exchange,提问作者AhmFM
相关产品推荐
相关产品推荐

