Bash

通過 ssh 執行命令時,while 循環內的反引號問題

  • March 16, 2017

這個問題有點複雜。我將嘗試詳細解釋。

我有兩台機器,一台是本地的,另一台說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'

引用自:https://unix.stackexchange.com/questions/351890