Bash

如何解析 ssh 遠端命令行參數

  • December 19, 2020

我已經看到了有關需要對遠端 ssh 命令的參數進行雙重轉義的問題和答案。我的問題是:第二次解析究竟在何時何地完成?

如果我執行以下命令:

$ ssh otherhost pstree -a -p

我在輸出中看到以下內容:

 |-sshd,3736
 |   `-sshd,1102
 |       `-sshd,1109
 |           `-pstree,1112 -a -p

pstree遠端命令 ( )的父程序是sshd,那裡似乎沒有任何 shell 可以解析遠端命令的命令行參數,因此似乎不需要雙引號或轉義(但它絕對是)。相反,如果我先在那裡 ssh 並獲得一個登錄 shell,然後執行,pstree -a -p我會在輸出中看到以下內容:

 ├─sshd,3736
 │   └─sshd,3733
 │       └─sshd,3735
 │           └─bash,3737
 │               └─pstree,4130 -a -p

所以很明顯那裡有一個bashshell可以在這種情況下進行命令行解析。但是我直接使用遠端命令的情況,好像沒有shell,那為什麼還要雙引號呢?

總是有一個遠端外殼。在 SSH 協議中,客戶端向伺服器發送一個字元串來執行。SSH 命令行客戶端接受它的命令行參數,並在參數之間用空格連接它們。伺服器獲取該字元串,執行使用者的登錄 shell 並將該字元串傳遞給它。(更準確地說:伺服器執行在使用者數據庫中註冊為使用者 shell 的程序,向其傳遞兩個命令行參數:-c和客戶端發送的字元串。shell 不作為登錄 shell 呼叫:伺服器不將第零個參數設置為以-.)開頭的字元串

繞過遠端外殼是不可能的。該協議沒有任何類似於發送可以在伺服器上解析為 argv 數組的字元串數組。並且 SSH 伺服器不會繞過遠端 shell,因為這可能是一個安全限制:使用受限程序作為使用者的 shell 是一種提供受限帳戶的方法,該帳戶只允許執行某些命令(例如,rsync-only 帳戶或僅 git 帳戶)。

您可能看不到外殼,pstree因為它可能已經不見了。許多 shell 有一個優化,如果他們檢測到他們將要“執行這個外部命令,等待它完成,並以命令的狀態退出”,那麼 shell 就會執行“execve這個外部命令”。這就是您的第一個範例中發生的情況。對比以下三個命令:

ssh otherhost pstree -a -p
ssh otherhost 'pstree -a -p'
ssh otherhost 'pstree -a -p; true'

前兩個是相同的:客戶端向伺服器發送完全相同的數據。第三個發送一個 shell 命令,它破壞了 shell 的 exec 優化。

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