
當我的 SSH 連線無回應時,我可以使用 終止它<enter>~.
。但是,當連接響應時,轉義~
不起作用。它只是在控制台上列印一個蒂爾達。
因此,如果我想修改 SSH 連接埠轉送並按<enter>~C<enter>
,我得到的只是:
~C: command not found
(來自bash
,而不是來自ssh
。)
我需要做什麼才能讓 SSH 轉義鍵正常運作?
編輯:我發現了一個大線索:遠端 shell 實際上是ash
,而不是bash
。當我bash
在遠端電腦上運行時,SSH 轉義鍵起作用了!當我再次跑ash
進去bash
時ash
,它不起作用!
但這很奇怪。轉義金鑰應該被 SSH 客戶端捕獲,甚至不轉送到遠端 shell。那麼為什麼哪個遠端 shell 接收來自 SSH 的輸入很重要呢?
答案1
簡單的解決方法:運行cat
命令,然後輸入轉義序列。
預設情況下,該cat
命令將列印傳入的內容stdin
,因此在運行時不會發送轉義字符,您可以正常使用 ssh 轉義鍵。完成後就ctrl-c
退出cat
回殼了。
例子
如果需要,請開啟提示並cat
透過鍵入cat
並按 Enter 鍵來執行。
$
$ cat
現在輸入〜?
~?
Supported escape sequences:
~. - terminate connection (and any multiplexed sessions)
~B - send a BREAK to the remote system
~C - open a command line
~R - request rekey
~V/v - decrease/increase verbosity (LogLevel)
~^Z - suspend ssh
~# - list forwarded connections
~& - background ssh (when waiting for connections to terminate)
~? - this message
~~ - send the escape character by typing it twice
有用!現在只需輸入任何命令。然後按 Control-C 返回提示符號。
^C
$
答案2
我已經發現這個秘密了!
正如我在上面的“編輯”中發布的,遠程 shell 是 BusyBox ash
,而不是bash
.
來自libbb/lineedit.c:2336-2338
BusyBox 來源:
/* Print out the command prompt, optionally ask where cursor is */
parse_and_put_prompt(prompt);
ask_terminal();
它用於列印 中的命令提示字元ash
。但請注意,一旦列印提示,另一個被呼叫的函數ask_terminal
就會被呼叫。有什麼ask_terminal
作用?它會列印出以下字元:<ESCAPE>[6n
。
您永遠不會在終端機中看到這些字元。實際上,它們是 ANSI 終端控制轉義代碼。<ESC>[6n
是一個「查詢遊標位置」命令——它告訴終端模擬器發送回另一個 ANSI 轉義代碼,該程式碼告訴 shell 遊標(文字插入點)在終端機視窗中的位置。
因此,只要您按下Enter
,ash
就會列印出<ESC>[6n
,並將sshd
其傳遞回ssh
終端模擬器或從那裡傳遞到終端仿真器。在您按下 之前~
,您的終端模擬器會立即發送類似<ESC>[47;13R
標準輸入的內容,並ssh
透過連接將其傳遞到sshd
或從那裡傳遞到ash
,告訴ash
您的遊標在哪裡。
現在,SSH 客戶端其實並不知道這些 ANSI 轉義碼的意思。對於 SSH 來說,它們都只是從標準輸入讀取的字元。<ENTER>~C
SSH 客戶端看到的不是 ,而是<ENTER><ESC>[47;13R~C
,並且由於它沒有看到~
後面的內容Enter
,因此它不認為這是轉義碼。
問題是對此該怎麼辦。如果 OpenSSH 能夠理解終端發送的 ANSI 轉義字符並且~
在 ANSI 終端控制命令之後仍然接受轉義字符,那就太好了。我可能會向 OpenSSH 人員發送一個補丁,看看他們是否有興趣修復這個問題...
答案3
你問當然,SSH 客戶端轉義金鑰不應該像這樣工作?
是的,它應該這樣工作:
如果按Enter然後~,則不會出現~
提示中將執行轉義的字元ssh
。
如果再按一次~它將出現在您的提示符號上,並且它將作用於工作 shell(範例中的 bash),它將嘗試擴張並按其所知使用。
請注意,要工作~
必須是您的第一個行緩衝區,所以如果您輸入任何字符,並且在刪除所有行後,該行就不再存在新的並且您需要Enter再次按下。
當我按下時~?
我得到
支持的轉義序列:
~。 - 終止連線(以及任何多路復用會話)
~B - 向遠端系統發送 BREAK
~C - 開啟命令列
~R - 請求重新產生金鑰(僅限 SSH 協定 2)
~^Z - 掛起 ssh
~# - 列出轉送的連線
~ & - 後台 ssh(等待連線終止時)
~? - 此訊息
~~ - 透過鍵入兩次來發送轉義字元
(請注意,轉義字元僅在換行符之後立即被識別。)