不能将$ @的所有参数与sh -c一起使用

Seb*_*bMa 2 bash command-line-arguments

在脚本中,我有一个sh -c涉及的命令,$@但似乎只考虑了的第一项$@

$ set -- --no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
$ echo "$@"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
$ sh -c "echo $@"
--no-resume-playback
$ sh -c "echo ${@[*]}"
bash: echo ${@[*]}: bad substitution
Run Code Online (Sandbox Code Playgroud)

编辑1:如果我将$@数组复制到一个变量,它的工作原理:

$ args=("$@")
$ sh -c "echo ${args[*]}"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
Run Code Online (Sandbox Code Playgroud)

如何$@sh -c通话中使用所有参数?

Joh*_*ica 7

$@即使使用双引号引起来,并且看起来像一个单词,它也会扩展为单独的单词。您编写的命令扩展为:

sh -c "echo --no-resume-playback" https://www.facebook.com/TBN/videos/1580372468665943/
Run Code Online (Sandbox Code Playgroud)

运行命令时将echo --no-resume-playback$0设置为Facebook URL。echo --no-resume-playback不使用$0,因此已被有效丢弃。

您对拥有正确的想法${@[*]}。碰巧的是,这$@是一种具有独特语法的特殊情况:you want $*,它扩展为一个单词。

sh -c "echo $*"
Run Code Online (Sandbox Code Playgroud)

这有点危险,因为任何带有通配符的参数*都可能会扩展。为了安全起见,您需要以下更复杂的版本:

sh -c 'echo "$@"' sh "$@"
Run Code Online (Sandbox Code Playgroud)

"$@"作为参数传递给-c命令,以便我们可以依次"$@"在内部使用。请注意,我现在切换到单引号:我们希望子"$@"外壳扩展,而不是外壳扩展。

实际上,对于最大的学步制echo来说,也不是完全安全的。如果您尝试打印类似的字符串,-n则可能不会按字面意义打印,而是将其解释为选项。最安全的选择是使用printf

sh -c 'printf "%s\n" "$*"' sh "$@"
Run Code Online (Sandbox Code Playgroud)

  • 您可以将$ *和$ @作为访问命令行参数的未命名数组的方式。$ {@ [*]}`不起作用,因为数组的名称不是@@。我可以看到`$ {[@@}}`和`$ {[*]}`的参数,也许省略了名称。 (2认同)