如何在Bash脚本中构造包含空格的数组元素
原因说明
你在命令行直接定义数组b=('1 2' '3 4')时,Shell会先做语法解析,识别到单引号属于语法标记,会把单引号包裹的内容作为整体处理,不会按内部空格拆分元素。
而脚本中的写法a="'1 2' '3 4'"; b=($a)会触发Shell的变量展开顺序问题:Shell会先完成变量$a的展开,再做单词拆分,此时$a里的单引号已经失去了语法标记的作用,只会被当做普通字符处理,所以会按默认的IFS(空格、制表符、换行符)把内容拆分成'1、2'、'3、4'四个独立的数组元素,就出现了你看到的异常结果。
解决方法
方法1:直接定义数组(最推荐,无安全风险)
如果不需要提前把元素存到普通字符串变量,直接和命令行写法一致即可:
#!/bin/bash # 直接定义带空格元素的数组 b=('1 2' '3 4') echo "${b[0]}" # 输出1 2 echo "${b[1]}" # 输出3 4
方法2:用readarray+xargs转换字符串为数组(适合Bash 4.4+,安全)
如果必须先把元素存到带引号的普通字符串变量中,可以用xargs自动处理引号边界,再转成数组:
#!/bin/bash a="'1 2' '3 4'" # xargs会自动识别引号包裹的内容作为单个项,readarray把每行内容转为数组元素 readarray -t b < <(xargs -n1 <<< "$a") echo "${b[0]}" # 输出1 2 echo "${b[1]}" # 输出3 4
方法3:用eval转换(仅适合信任的输入场景)
如果使用的是低版本Bash,可以用eval强制让Shell重新做语法解析,但是仅当你完全确定变量a的内容是安全、没有恶意代码的情况下使用:
#!/bin/bash a="'1 2' '3 4'" eval "b=($a)" echo "${b[0]}" # 输出1 2 echo "${b[1]}" # 输出3 4
额外注意事项
- 直接用
echo $b只会输出数组的第一个元素,是Bash的默认行为,建议明确写下标${b[0]}提升可读性。 - 所有变量展开场景尽量用双引号包裹(比如
"$a"、"${b[@]}"),避免意外的单词拆分和通配符展开。
内容的提问来源于stack exchange,提问作者Victor Lee
相关产品推荐
相关产品推荐

