![無法透過 ssh 運行命令](https://rvso.com/image/1711437/%E7%84%A1%E6%B3%95%E9%80%8F%E9%81%8E%20ssh%20%E9%81%8B%E8%A1%8C%E5%91%BD%E4%BB%A4.png)
我正在 FreeBSD 機器 (xxx.yyy.zzz.net) 上執行命令並取得輸出
命令
sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done
輸出
media RPM non-rotating
media RPM non-rotating
media RPM non-rotating
我正在嘗試使用 ssh 從另一台機器運行相同的命令
命令
ssh xxx.yyy.zzz.net sudo camcontrol devlist | grep -o 'ada[0-9]' | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done
錯誤
sudo: camcontrol: command not found
答案1
在您的命令中,每個內容|
都由您的本機 shell 解釋。最後一個參數ssh
看到的是devlist
。ssh
在本地調用(這並不奇怪),但第一個|
.
您收到的錯誤來自sudo
此程式碼片段:do sudo camcontrol identify $a
。它在本地運行,顯然camcontrol
在本地計算機上不可用。
您需要正確的轉義或引用。在這種情況下,您可能需要將整個遠端命令放在單引號中:
ssh xxx.yyy.zzz.net 'sudo camcontrol devlist | grep -o "ada[0-9]" | while read -r a ; do sudo camcontrol identify $a | grep rotating ; done'
請注意,我更改了您已有的單引號。 (新增的)單引號不僅將整個字串進行分組,以便ssh
取得它;它們還阻止了 的局部擴展$a
。
如果sudo
要詢問您的密碼,則需要一個偽終端。您可以-t
使用選項強制偽終端分配ssh
(所以它看起來像ssh -t xxx.yyy.zzz.net …
)。注意ssh -t
在遠端分配偽終端。遠端sudo
提示其 stderr,但隨後 stdout 和 stderr 被該偽終端「列印」(就像它們通常列印到控制台一樣),此時您無法再區分它們;合併的流被捕獲並傳輸到本地端,然後傳輸到標準輸出。如果沒有-t
單獨傳輸遠端 stdout 和 stderr,請轉到本地端的 stdout 和 stderr,這些最終會合併(或不合併,如果重定向)到您所看到的內容。這意味著-t
您無法(在本機)區分遠端 stderr 和遠端 stdout。如果您需要在本地進一步處理(重定向)輸出並使用,-t
則任何提示sudo
都會幹擾。
另外,您可能想要雙引號$a
(即使在您的第一個不使用的命令中ssh
)。看為什麼我的 shell 腳本會因為空格或其他特殊字元而卡住?