从包含双引号的数组中展开参数

expand arguments from array containing double quotes

我想用从bash中的数组构建的参数调用程序。

我想bash打电话给:

echo -arg1=simple -arg2="some spaces"

来自 array=(echo -arg1=simple "-arg2=\"some spaces\"") 或类似的(我可以调整项目的创建方式)。

问题

"${array[@]}" bash 通话:

echo -arg1=simple '-arg2="some spaces"'

但我不想要单引号。如何正确构建和扩展数组?

示例代码

#!/bin/bash
set -x

array=()
array+=(echo)
array+=(-arg1=simple)
array+=("-arg2=\"some spaces\"")

"${array[@]}"
"${array[*]}"
${array[@]}
${array[*]}

产生的调用

echo -arg1=simple '-arg2="some spaces"'
'echo -arg1=simple -arg2="some spaces"'
echo -arg1=simple '-arg2="some' 'spaces"'
echo -arg1=simple '-arg2="some' 'spaces"'

你可以简单地这样做,不需要在数组中保留 echo:

#!/bin/bash -x

array=()
array+=(-arg1=simple)
array+=(-arg2="some spaces")

echo "${array[@]}"

调用 echo 的结果是接收两个单词作为参数,-arg1=simple-arg2="some spaces",就像您写的一样:

echo -arg1=simple -arg2="some spaces"

或者,您可以在一行中定义数组,使用 declare:

declare -a array=(-arg1=simple -arg2="some spaces")

查看如何展开,可以使用printf(这里使用==只是为了清楚地显示每个参数的开始和结束):

$ printf "==%s==\n" "${array[@]}"
==-arg1=simple==
==-arg2=some spaces==

请注意 ${array[@]} 周围引号的重要性。他们确保数组中的每个元素都只扩展为一个单词(就像扩展前在 shell 中引用一样)。比较:

$ printf "==%s==\n" ${array[@]}
==-arg1=simple==
==-arg2=some==
==spaces==

更新。如果你想将它扩展到 -arg2="some spaces"(虽然不确定你为什么想要它),只需将它放在定义的单引号内:

$ declare -a array=(-arg1=simple '-arg2="some spaces"')
$ echo "${array[@]}"
-arg1=simple -arg2="some spaces"
$ printf "==%s==\n" "${array[@]}"
==-arg1=simple==
==-arg2="some spaces"==

"${array[@]}" 是正确的。 -x 选项只是选择一种规范的方式来显示需要引用的值,'-arg2="some spaces"' 等同于 "-arg2=\"some spaces\"".