Bash中打印字典/数组内容时出现的开头前导0是什么原因
获取所有节点IP和端口号
原问题代码:
node_ip_port=$(ringsh supervisor ringStatus DATA |grep "Node:"|awk '{print $3}' |awk 'BEGIN {FS=":"} {print $1, $2}') echo ${!node_ip_port[*]}$'\n' for port in "${!node_ip_port[@]}"; do echo "$port ${node_ip_port[$port]}" done
执行后输出开头出现多余前导0:
0 0 172.16.254.101 8084 172.16.254.101 8085 172.16.254.101 8086 ...
问题原因
前导0完全是Bash数组赋值语法错误导致的:
- 代码中
node_ip_port=$(...)是普通字符串变量赋值,不是数组赋值。Bash中如果要把命令输出的多组结果存为数组,必须使用数组专用的赋值语法,否则Bash会把整个命令输出的整段字符串,当做下标为0的单个数组元素处理。 - 第一行单独打印的
0,来自echo ${!node_ip_port[*]}语句:此时Bash识别到的数组只有0这一个有效索引,所以直接输出0,后面拼接的换行符就形成了0加空行的效果。 - 循环第一行输出前的
0,也是该下标0的打印结果:整段包含所有节点IP端口的字符串被存在下标0的位置,后续行前没有索引,是因为字符串内部的换行被直接输出,但这些行本身并不是独立的数组元素。
解决方法
根据实际需求二选一即可:
方案1:按行存储为普通索引数组
如果只需要把每组IP 端口作为独立元素存储,用mapfile按行读取命令输出,避免空格、换行导致的元素分割错误:
# 按行读取命令输出,每行对应一个数组元素 mapfile -t node_ip_port < <(ringsh supervisor ringStatus DATA | grep "Node:" | awk '{print $3}' | awk 'BEGIN {FS=":"} {print $1, $2}') echo "数组下标列表:${!node_ip_port[*]}" echo for idx in "${!node_ip_port[@]}"; do echo "$idx ${node_ip_port[$idx]}" done
执行后下标会从0开始连续递增,每个下标对应一组IP和端口,不会出现多余前导0。
方案2:存储为端口为键的关联数组
如果原逻辑是要以端口为键、对应IP为值(从循环变量名port判断符合该场景),需要先声明关联数组,再逐行解析赋值:
# 声明关联数组 declare -A node_ip_port # 逐行读取解析结果,以端口为键存入数组 while read -r ip port; do node_ip_port[$port]=$ip done < <(ringsh supervisor ringStatus DATA | grep "Node:" | awk '{print $3}' | awk 'BEGIN {FS=":"} {print $1, $2}') echo "所有端口列表:${!node_ip_port[*]}" echo for port in "${!node_ip_port[@]}"; do echo "$port ${node_ip_port[$port]}" done
内容的提问来源于stack exchange,提问作者Angelo Fazzina
相关产品推荐
相关产品推荐

