如何将引用的参数传递给另一个程序

How to pass quoted parameters to another program

在 bash 脚本中,我需要将参数传递给另一个程序。参数中有空格,所以必须用引号引起来。在这个简单的案例 1 中一切正常:

/bin/echo /some/command --param="abc def ghi"

输出:

/some/command --param=abc def ghi

如果我想让 bash 脚本更复杂,问题就开始了,在情况 2 和 3 中参数值不知何故发生了变化:

FOO="ghi"
DEFAULTS="--param=\"abc def $FOO\""
/bin/echo /some/command $DEFAULTS

DEFAULTS='--param="abc def '$FOO'"'
/bin/echo /some/command $DEFAULTS

输出:

/some/command --param="abc def ghi"
/some/command --param="abc def ghi"

abc def ghi 周围的双引号在 2 和 3 中显示,而在 1 中没有显示。

让 /some/command 实际打印它接收到的第一个参数可以更好地说明这一点。这里整个字符串 "abc def ghi" 作为 param 参数的值接收:

perl -le'print $ARGV[0]' param="abc def ghi"

输出(右):

param=abc def ghi

但这里只收到 "abc,有一个前导引号:

DEFAULTS='param="abc def ghi"'
perl -le'print $ARGV[0]' $DEFAULTS

DEFAULTS="param=\"abc def ghi\""
perl -le'print $ARGV[0]' $DEFAULTS

输出(错误):

param="abc
param="abc

我如何使用 bash 动态构造一个像 param="abc def ghi" 这样的字符串并能够将它原封不动地传递给另一个命令?

你快到了。您只需要将 $DEFAULTS 放在双引号中,这样 bash 就不会拆分单词。

DEFAULTS='param="ac def ghi"'
perl -le'print $ARGV[0]' "$DEFAULTS"

输出:

param="ac def ghi"

使用数组;这就是引入它们的原因。

FOO="ghi"
# Contains one element, but not the literal quotes
DEFAULTS=(--param="abc def $FOO")
# command gets 1 argument, the single element of the array
/some/command "${DEFAULTS[@]}"

# Two elements
DEFAULTS=(--param="abc def $FOO" --other="foo bar")
# command gets 2 arguments
/some/command "${DEFAULTS[@]}"