Sil*_*Fox 1 shell bash function
foo (){
sudo -- sh -c "cd /home/rob; echo \"$@\""
}
Run Code Online (Sandbox Code Playgroud)
我正在尝试创建一个 bash 函数.bashrc,将 sudo 更改为特定目录,然后运行 Python 命令。出于演示目的,我在上面的示例中将其更改为 echo。
尽管我已引用$@将所有参数传递给 echo 命令,但它仅适用于一个:
$ foo 1
1
$ foo 1 2
2": -c: line 0: unexpected EOF while looking for matching `"'
2": -c: line 1: syntax error: unexpected end of file
Run Code Online (Sandbox Code Playgroud)
是什么赋予了?如何向该函数传递多个参数?
添加set -v到您的函数中,您将看到发生了什么:
$ f (){ set -v; sudo -- sh -c "cd /tmp; echo \"$@\""; }
$ f 1 2
+ sudo -- sh -c 'cd /tmp; echo "1' '2"'
Run Code Online (Sandbox Code Playgroud)
怎么了?您的使用$@创建了两个字符串,并用单引号引起来cd /tmp; echo "1和2"。$*如果您不想进行这种拆分,则可以使用。请参阅 bash 手册页中有关特殊参数的部分:
@ ...当扩展发生在双引号内时,每个参数都会扩展为一个单独的单词。... 如果... 在一个单词内,第一个参数的扩展与原始单词的开头部分连接,最后一个参数的扩展与原始单词的最后部分连接。
因此,在您的情况下,单个字符串(或单词)“xxx$@yyy”扩展为 2 个字符串“xxx1”和“2yyy”。set -- 1 2 3您可以使用set 来测试它$@,然后使用printf ">%s<" "$@"来查看变为的单词数"$@"(因为 printf 将为每个参数重复格式):
$ set -- 1 2 3
$ printf ">%s< " "x$@y"
>x1< >2< >3y<
$ printf ">%s< " "x$*y"
>x1 2 3y<
Run Code Online (Sandbox Code Playgroud)
如果您想将参数传递给sh -c command一个 hack,请将它们作为参数放置在单个命令之后,但这可能不适用于所有 shell:
f (){ set -v; sudo -- sh -c 'cd /tmp; echo "$@"' sh "$@"; }
f 1 2
+ sudo -- sh -c 'cd /tmp; echo "$@"' sh 1 2
Run Code Online (Sandbox Code Playgroud)
额外的sh参数是因为第一个参数被 shell 作为进程的名称。