不能将 $@ 的所有参数与 sh -c 一起使用
Cannot use all arguments of $@ with sh -c
在脚本中,我有一个涉及 $@
的 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
编辑 1:如果我将 $@
数组复制到一个变量中,它会起作用:
$ args=("$@")
$ sh -c "echo ${args[*]}"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
如何在 sh -c
调用中使用 $@
的所有参数?
$@
扩展为单独的词,即使它在双引号中并且看起来像一个词。您编写的命令扩展为:
sh -c "echo --no-resume-playback" https://www.facebook.com/TBN/videos/1580372468665943/
命令 运行 是 echo --no-resume-playback
,[=16=]
设置为 Facebook URL。 echo --no-resume-playback
没有使用 [=16=]
,所以它实际上被丢弃了。
你对 ${@[*]}
的想法是正确的。碰巧的是,$@
是一种具有独特语法的特例:您需要 $*
,它扩展为一个单词。
sh -c "echo $*"
这有点危险,因为任何带有像 *
这样的通配符的参数都可能被扩展。如果你想安全起见,你需要这个更复杂的版本:
sh -c 'echo "$@"' sh "$@"
这会将 "$@"
作为参数转发给 -c
命令,这样我们就可以在里面使用 "$@"
。请注意,我现在已切换到单引号:我们希望 subshell 扩展 "$@"
,而不是外部 shell.
实际上,对于最大程度的迂腐,echo
也不是完全安全的。如果你尝试打印一个像 -n
这样的字符串,它可能不会按字面打印,而是被解释为一个选项。最安全的选择是使用 printf
:
sh -c 'printf "%s\n" "$*"' sh "$@"
您是否尝试过使用 $*
扩展?
我得到以下信息:
$ sh -c "echo $*"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
符合您的需求吗?
在脚本中,我有一个涉及 $@
的 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
编辑 1:如果我将 $@
数组复制到一个变量中,它会起作用:
$ args=("$@")
$ sh -c "echo ${args[*]}"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
如何在 sh -c
调用中使用 $@
的所有参数?
$@
扩展为单独的词,即使它在双引号中并且看起来像一个词。您编写的命令扩展为:
sh -c "echo --no-resume-playback" https://www.facebook.com/TBN/videos/1580372468665943/
命令 运行 是 echo --no-resume-playback
,[=16=]
设置为 Facebook URL。 echo --no-resume-playback
没有使用 [=16=]
,所以它实际上被丢弃了。
你对 ${@[*]}
的想法是正确的。碰巧的是,$@
是一种具有独特语法的特例:您需要 $*
,它扩展为一个单词。
sh -c "echo $*"
这有点危险,因为任何带有像 *
这样的通配符的参数都可能被扩展。如果你想安全起见,你需要这个更复杂的版本:
sh -c 'echo "$@"' sh "$@"
这会将 "$@"
作为参数转发给 -c
命令,这样我们就可以在里面使用 "$@"
。请注意,我现在已切换到单引号:我们希望 subshell 扩展 "$@"
,而不是外部 shell.
实际上,对于最大程度的迂腐,echo
也不是完全安全的。如果你尝试打印一个像 -n
这样的字符串,它可能不会按字面打印,而是被解释为一个选项。最安全的选择是使用 printf
:
sh -c 'printf "%s\n" "$*"' sh "$@"
您是否尝试过使用 $*
扩展?
我得到以下信息:
$ sh -c "echo $*"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
符合您的需求吗?