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

Posted

技术标签:

【中文标题】从包含双引号的数组中展开参数【英文标题】:expand arguments from array containing double quotes 【发布时间】:2018-01-01 16:47:49 【问题描述】:

我想在 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 为了使示例更简单,我可以编写 echo "$array[@]" 并从数组中省略它。 单引号实际上并没有做任何事情;这就是-x 选项选择显示第二个参数的方式。 "$array[@]" 是正确的。 【参考方案1】:

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

【讨论】:

感谢您的澄清! 我不希望双引号在里面转义。 echo 产生我想要的命令行,但我需要 bash 来调用它而不是显示它。【参考方案2】:

你可以简单地这样做,不需要在数组中保留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"==

【讨论】:

感谢您对 printf 的提示,但我希望它扩展到 -arg2="some spaces" 而不是 -arg2=some spaces 当我这样包装它时:echo "echo $array[@]" | source /dev/stdin bash 似乎调用了echo -arg1=simple '-arg2=some spaces' 这不是我正在搜索的内容,但 cmake 似乎接受了 (cmake .. -bla -bla '-DCMAKE_CXX_FLAGS=-bla -bla')。 您的更新会起作用,但在实际代码中 some spaces$cxx_flags[*] 并且单引号不会扩展此变量:/ @bibermann,这是至关重要的细节。请更新问题,因为这会改变一切。请告诉确切你想做什么。帮助我们,让我们为您提供帮助! CMake 也接受我在问题中得到的带有单引号的版本。我没试过,只是看起来不对。不过,您的更新回答了非特定问题,所以我接受。

以上是关于从包含双引号的数组中展开参数的主要内容,如果未能解决你的问题,请参考以下文章

从批处理文件中的变量中删除双引号会导致 CMD 环境出现问题

CMD命令中的参数带有双引号,如何转义双引号?

JS:JSON的属性名必须要加双引号吗?

从json响应swift中删除数组中的双引号

CMD命令中的参数带有双引号,如何转义双引号?

shell中的参数引用