如何在Bash脚本for循环中跳过数组当前元素并生成新数组
修正Bash数组遍历与元素排除的问题
我帮你看看这段Bash代码的问题哈~首先你遇到的[[192.168.110.165: command not found错误,是因为Bash里[[这个条件判断命令和后面的表达式之间必须要有空格!你写的if [["${HOSTS[$j]}" = "${HOSTS[$i]}"]]里,[[和"${HOSTS[$j]}"连在一起了,系统就把它当成一个不存在的命令了。另外还有数组传递的小问题,下面是完整的修正方案:
主要修改点
- 修复
[[的语法:[[和表达式之间必须加空格,同时我们可以直接判断元素不等,简化逻辑 - 传递数组给函数时,用
"${args[@]}"代替${args[*]},这样能保证数组每个元素作为独立参数传递 - 可选优化:可以用数组切片的方式替代嵌套循环,更高效地排除当前元素
修正后的完整代码
create_nodes_directories(){ read -r CURRENTHOST _ < <(hostname -I) HOSTS=(192.168.110.165 192.168.110.166 192.168.110.167) for i in "${!HOSTS[@]}" ; do # 初始化空数组 args=() # 遍历数组排除当前元素 for j in "${!HOSTS[@]}" ; do # 注意[[前后的空格,直接判断不等 if [[ "${HOSTS[$j]}" != "${HOSTS[$i]}" ]]; then args+=("${HOSTS[$j]}") fi done # 添加CURRENTHOST到数组末尾 args+=("$CURRENTHOST") # 正确传递数组给函数 create_genesis_start_file "${args[@]}" # 可选:打印args数组验证(调试用) echo "第$((i+1))次迭代,args数组内容:${args[@]}" done }
优化版(用数组切片替代嵌套循环)
如果你的Bash版本支持数组切片(大部分现代Bash都支持),可以把嵌套循环换成更简洁的写法,避免内层循环:
create_nodes_directories(){ read -r CURRENTHOST _ < <(hostname -I) HOSTS=(192.168.110.165 192.168.110.166 192.168.110.167) for i in "${!HOSTS[@]}" ; do # 用切片拼接出排除当前元素的数组:前i个元素 + i之后的所有元素 args=("${HOSTS[@]:0:i}" "${HOSTS[@]:i+1}") args+=("$CURRENTHOST") create_genesis_start_file "${args[@]}" # 调试打印 echo "第$((i+1))次迭代,args数组内容:${args[@]}" done }
预期输出验证
当HOSTS=(192.168.110.165 192.168.110.166 192.168.110.167)时,调试打印会输出:
第1次迭代,args数组内容:192.168.110.166 192.168.110.167 [你的CURRENTHOST IP] 第2次迭代,args数组内容:192.168.110.165 192.168.110.167 [你的CURRENTHOST IP] 第3次迭代,args数组内容:192.168.110.165 192.168.110.166 [你的CURRENTHOST IP]
内容的提问来源于stack exchange,提问作者Varsh
相关产品推荐
相关产品推荐

