这些命令如何导致不同的输出?ssh命令引用有什么不同?
⋊> ssh host bash -c 'cd /tmp; pwd'
/home/manu
⋊> ssh host "bash -c 'cd /tmp; pwd'"
/tmp
到类似的问题here的回答说:
尾随参数组合成被传递到作为参数传递给你的登录shell对-c选项一个字符串远程机器。
在*
的情况下,我可以理解这一点,但在本例中哪些部分将在本地进行评估?另外,在bash命令之前的--
没有帮助。
这些命令如何导致不同的输出?ssh命令引用有什么不同?
⋊> ssh host bash -c 'cd /tmp; pwd'
/home/manu
⋊> ssh host "bash -c 'cd /tmp; pwd'"
/tmp
到类似的问题here的回答说:
尾随参数组合成被传递到作为参数传递给你的登录shell对-c选项一个字符串远程机器。
在*
的情况下,我可以理解这一点,但在本例中哪些部分将在本地进行评估?另外,在bash命令之前的--
没有帮助。
这里要理解的是,ssh
只是简单地连接它的参数(与$*
一样),并将该连接的字符串传递给sh -c
。
因此,在的情况下:
ssh josh-play bash -c 'cd /tmp; pwd'
... SSH运行:
sh -c 'bash -c cd /tmp; pwd'
...因此,SH运行:
bash -c cd /tmp
pwd
。 ..和你可以测试自己,bash -c cd /tmp
并没有太多的用处ul(它运行的脚本文本仅包含cd
; /tmp
作为参数存储,但脚本文本从不读取其参数,因此没有意义)。此外,只要bash
退出,我们又回到了父项sh
过程中,其中cd
从未运行过。
传递给你的外壳句法引号完全丧失,而pwd
是由您手动触发(在这种用法,只是调用cd
不带任何参数的bash
不会调用 - /tmp
是$1
,但该脚本作为参数传递给cd
从不解除引用该变量),而是通过ssh隐式调用的sh
。
如果你知道你的远程sh
由bash或ksh的提供 - 外壳支持$''
分机 - 你可以做任意argv数组以下(在这种情况下bash
,-c
,cd /tmp; pwd
) :
# ask your shell to generate an eval-safe quoted form of your argument list
printf -v rmt_cmd '%q ' bash -c 'cd /tmp; pwd'
# pass that through to be run by the remote sh -c
ssh josh-play "$rmt_cmd"
需要说明上述的是,如果您的参数列表可以包含换行符或隐藏字符,printf %q
在bash或ksh可以在形式POSIX SH不保证能够读取逃避它。为了避免这种情况:
# ask your shell to generate an eval-safe quoted form of your argument list
printf -v rmt_cmd '%q ' bash -c 'cd /tmp; pwd'
# ...and use bash to evaluate that quoted form.
ssh josh-play 'exec bash -s' <<<"$rmt_cmd"
看到这个职位:奇怪的“上海-c”行为时,通过SSH运行(http://unix.stackexchange.com/questions/340221/strange-sh-c-behavior- when-run-through-ssh) – codeforester
@codeforester,...尽管我认为这应该超出'sh -c',因为这肯定是一个在其他场景中相关的问题。 –