【问题标题】: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[@]}" 是正确的。

标签: arrays bash quotes


【解决方案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 也接受我在问题中得到的带有单引号的版本。我没试过,只是看起来不对。不过,您的更新回答了非特定问题,所以我接受。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-08
  • 1970-01-01
  • 1970-01-01
  • 2020-07-25
  • 2023-04-07
  • 2019-12-23
相关资源
最近更新 更多