You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何不使用eval将带嵌套引号的字符串转为Bash数组?

不使用eval实现带引号字符串的正确数组拆分

先看示例代码里的问题:

input="a b '1 2 3' c"

arr=($input); printf '%s|' "${arr[@]}"
# 输出:a|b|'1|2|3'|c|

eval "arr=($input)"; printf '%s|' "${arr[@]}"
# 输出:a|b|1 2 3|c|

直接执行arr=($input)时,Bash会按空格拆分所有内容,把带引号的'1 2 3'拆成了'1、2、3'三个元素;而eval能正确识别引号,把1 2 3当作单个元素,但eval存在安全风险,容易被注入恶意命令。

下面提供两种不用eval的实现方式:

方法一:用read循环读取xargs处理后的元素

input="a b '1 2 3' c"
arr=()
# xargs自动解析引号,将每个元素单独输出为一行,再循环读取到数组
while IFS= read -r item; do
    arr+=("$item")
done < <(xargs printf '%s\n' <<< "$input")

printf '%s|' "${arr[@]}"
# 输出:a|b|1 2 3|c|

方法二:用readarray(mapfile)批量读取

如果你的Bash版本在4.0及以上,可以用更简洁的readarray(别名mapfile):

input="a b '1 2 3' c"
# xargs解析引号后按行输出,readarray直接将每行内容存入数组
readarray -t arr < <(xargs printf '%s\n' <<< "$input")

printf '%s|' "${arr[@]}"
# 输出:a|b|1 2 3|c|

原理说明

xargs会按照Shell的分词规则解析输入字符串,自动识别单引号、双引号包裹的内容,将其视为单个元素;随后用printf '%s\n'把每个元素输出为单独一行,再通过进程替换< <(...)传递给read或readarray,最终把每个元素正确存入数组,完全规避了eval的安全隐患。

内容的提问来源于stack exchange,提问作者Marcus Whybrow

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 18:22:52