提问人:bibermann 提问时间:7/26/2017 更新时间:7/27/2017 访问量:1830
从包含双引号的数组中展开参数
expand arguments from array containing double quotes
问:
我想用从 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"'
答:
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/stdin
echo -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
评论
echo
echo "${array[@]}"
-x
"${array[@]}"