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

expand arguments from array containing double quotes

提问人:bibermann 提问时间:7/26/2017 更新时间:7/27/2017 访问量:1830

问:

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

我想让 bash 调用:

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

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

问题

使用 bash 调用:"${array[@]}"

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"'
Arrays Bash 行情

评论

0赞 anubhava 7/26/2017
你为什么要保留在你的阵列中?echo
0赞 bibermann 7/26/2017
为了使示例更简单,我可以编写并从数组中省略它。echo "${array[@]}"
0赞 chepner 7/26/2017
单引号实际上并没有做任何事情;这就是该选项选择显示第二个参数的方式。 是正确的。-x"${array[@]}"

答:

3赞 randomir 7/26/2017 #1

您可以简单地这样做,无需保留在数组内: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==

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

$ 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"==

评论

0赞 bibermann 7/27/2017
感谢您的提示 printf,但我希望它扩展到而不是-arg2="some spaces"-arg2=some spaces
0赞 bibermann 7/27/2017
当我这样包装它时:bash 似乎调用了这并不完全是我正在搜索的内容,但 cmake 似乎接受了这一点()。echo "echo ${array[@]}" | source /dev/stdinecho -arg1=simple '-arg2=some spaces'cmake .. -bla -bla '-DCMAKE_CXX_FLAGS=-bla -bla'
0赞 bibermann 7/27/2017
您的更新可以工作,但是在实际代码中,使用单引号时,此变量不会扩展:/some spaces${cxx_flags[*]}
1赞 randomir 7/27/2017
@bibermann,这是至关重要的细节。请更新问题,因为这会改变一切。请确切地说出你想做什么。帮助我们,这样我们才能为您提供帮助!
1赞 bibermann 7/27/2017
CMake 也接受我在问题中得到的带有单引号的版本。我没有尝试过,只是看起来不对劲。尽管如此,您的更新回答了非特定问题,所以我接受这一点。
5赞 chepner 7/26/2017 #2

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

评论

0赞 bibermann 7/27/2017
谢谢你的澄清!
0赞 bibermann 7/27/2017
我不希望双引号在里面逃脱。生成我想要的命令行,但我需要 bash 来调用它而不是显示它。echo