在脚本中,我有一个涉及sh -c
的{{1}}命令,但似乎只考虑了$@
的第一项:
$@
编辑1:如果我将$ 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
数组复制到一个变量中,它将起作用:
$@
如何在$ args=("$@")
$ sh -c "echo ${args[*]}"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
调用中使用$@
的所有参数?
答案 0 :(得分:7)
$@
会扩展为单独的单词,即使使用双引号并且看起来像一个单词也是如此。您编写的命令将扩展为:
sh -c "echo --no-resume-playback" https://www.facebook.com/TBN/videos/1580372468665943/
命令运行为echo --no-resume-playback
,其中$0
设置为Facebook URL。 echo --no-resume-playback
不使用$0
,因此有效地将其丢弃。
您对${@[*]}
有正确的想法。碰巧,$@
是一种具有独特语法的特例:您想要$*
,它可以扩展为一个单词。
sh -c "echo $*"
这有点危险,因为带有通配符(例如*
)的任何参数都可以扩展。为了安全起见,您需要以下更复杂的版本:
sh -c 'echo "$@"' sh "$@"
这会将"$@"
作为-c
命令的参数转发,以便我们可以依次在其中使用"$@"
。请注意,我现在切换到单引号:我们希望子外壳展开"$@"
,而不是外壳。
实际上,对于最大的步伐echo
也不是完全安全的。如果您尝试打印类似-n
的字符串,则可能无法按原样打印,而是将其解释为一个选项。最安全的选择是使用printf
:
sh -c 'printf "%s\n" "$*"' sh "$@"
答案 1 :(得分:1)
您是否尝试过使用$*
扩展?
我得到以下信息:
$ sh -c "echo $*"
--no-resume-playback https://www.facebook.com/TBN/videos/1580372468665943/
符合您的需求吗?