通過 ssh 執行命令時,while 循環內的反引號問題
這個問題有點複雜。我將嘗試詳細解釋。
我有兩台機器,一台是本地的,另一台說
192.168.1.2
。我在本地機器中設置了以下變數
CHECK="/home/test/Desktop/"
test
在我的本地機器和遠端機器中都存在一個名為的使用者。我想通過 ssh 從本地執行以下命令。ssh -n test@192.168.1.2 "until [ `cat $CHECK/samplefile | grep "string"` ]; do touch $CHECK/success; done"
我想要實現的是,我想檢查遠端機器中名為“string”的條目的 $CHECK/samplefile。一旦找到它,我想退出
until
循環並走得更遠。但是當我執行此命令時,我收到以下錯誤消息。
cat: /home/test/Desktop//samplefile: No such file or directory
但我很確定我的遠端機器在
test
使用者的桌面中包含文件名 samplefile。在進一步的研究中,我開始知道until
反引號中給出的條件語句實際上執行在local
而不是remote
(我的本地在桌面中不包含這樣的文件)。此外,直到循環中的其餘命令工作正常,並且在遠端電腦的桌面中創建了一個名為 success 的新文件。我不確定問題是反引號還是直到。在過去的 3 個小時裡,我一直堅持這一點。有什麼建議麼?
正如您在問題中註意到的那樣,這種替換:
`cat $CHECK/samplefile | grep "string"`
在您的本地機器上執行。您可以通過以下方式輕鬆修復它:
ssh -n test@192.168.1.2 \ "until { cat ""$CHECK""/samplefile | grep ""string""; }; do \ touch ""$CHECK""/success; \ done"
如您所見,您不需要任何替換,而是解析
$CHECK
變數。您可以將條件指令放入{...}
列表中,現在列表的退出程式碼對until
指令起決定性作用。
你是對的,它是引用。通過使用雙引號將遠端命令括起來,您是在告訴本地 shell 解釋它可以傳遞給 ssh 會話的任何內容。在這種情況下,
cat
命令。如果將命令用單引號括起來,就不會出現這個問題,但也無法擴展在單引號之外定義的變數。
本地文件:
bash-[501]$ echo $(hostname) > /tmp/samplefile bash-[506]$ echo $(cat /tmp/samplefile) tank
創建遠端文件:
bash-[502]$ ssh evil 'echo $(hostname) > /tmp/samplefile' bash-[501]$ cat /tmp/samplefile evil
嘗試用雙引號查看遠端文件:
bash-[508]$ ssh evil "echo `cat /tmp/samplefile`" tank
嘗試用單引號查看遠端文件:
bash-[509]$ ssh evil 'echo `cat /tmp/samplefile`' evil
將文件定義為要在遠端端處理的變數:
bash-[527]$ ssh evil 'F=/tmp/samplefile; cat $F' evil
在您的情況下,將命令用單引號括起來,並
$CHECK
在這些引號內定義,足以將所有內容髮送到遠端端進行解釋。ssh -n test@192.168.1.2 'CHECK=/home/test/Desktop; until [ `cat $CHECK/samplefile | grep "string"` ]; do touch $CHECK/success; done'