這些命令如何導致不同的輸出?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',因爲這肯定是一個在其他場景中相關的問題。 –