以下示例返回“a b”而不是预期的“ab c”:
test() { bash -c "testargs() { echo \$@; }; testargs $@"; }
test "a b" c
看来这是一个引用问题。如何在不使用“$*”的情况下解决这个问题?
答案1
$@
几乎应该只以 形式使用"$@"
,单独一句话。展开时"stuff$@"
,会产生一个列表,其中包含stuff
前置的第一个位置参数,然后是其他位置参数。例如,如果位置参数是foo
and bar
,您将得到两个单词:stufffoo
and bar
。这是你的问题之一。
另一个问题是,使用 时sh -c
,第一个非选项参数将成为可用的脚本名称$0
。后续的非选项参数成为位置参数。所以sh -c 'echo "$@"' foo bar qux
打印bar qux
- foo
is in $0
, bar
in$1
和qux
in $2
。
要将函数的参数传递给脚本,请$@
在脚本中使用(而不是像您那样在函数中使用 -"stuff$@"
由于双引号而在执行函数的 shell 中展开)。并占$0
.
test() { bash -c 'testargs() { echo "$@"; }; testargs "$@"' myscript "$@"; }
答案2
双引号中的 $@ 扩展为多个单词。bash -c
接受细绳作为参数,但后面可以跟其他的字然后将其分配给以 $0 开头的位置参数。
因此,您可以将参数发送到内部代码,bash -c
如下所示:
Test () { bash -c 'echo $@' -- "$@" ; }
Test "a b" c
这也适用于您的情况:
Test () { bash -c 'testargs() { echo $@ ; } ; testargs $@' -- "$@" ; }
Test "a b" c
如果要保留多字参数,请添加双引号:
Test () {
bash -c 'testargs() {
for a in "$@" ; do
echo "$a"
done
}
testargs "$@"' \
-- "$@"
}
Test "a b" c
我使用了Test
,因为test
已经存在并且可能会让读者感到困惑。