SSH 轉義鍵(“~”)僅在連接卡住時才起作用?

SSH 轉義鍵(“~”)僅在連接卡住時才起作用?

當我的 SSH 連線無回應時,我可以使用 終止它<enter>~.。但是,當連接響應時,轉義~不起作用。它只是在控制台上列印一個蒂爾達。

因此,如果我想修改 SSH 連接埠轉送並按<enter>~C<enter>,我得到的只是:

~C: command not found

(來自bash,而不是來自ssh。)

我需要做什麼才能讓 SSH 轉義鍵正常運作?

編輯:我發現了一個大線索:遠端 shell 實際上是ash,而不是bash。當我bash在遠端電腦上運行時,SSH 轉義鍵起作用了!當我再次跑ash進去bashash,它不起作用!

但這很奇怪。轉義金鑰應該被 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-2338BusyBox 來源:

/* 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 遊標(文字插入點)在終端機視窗中的位置。

因此,只要您按下Enterash就會列印出<ESC>[6n,並將sshd其傳遞回ssh終端模擬器或從那裡傳遞到終端仿真器。在您按下 之前~,您的終端模擬器會立即發送類似<ESC>[47;13R標準輸入的內容,並ssh透過連接將其傳遞到sshd或從那裡傳遞到ash,告訴ash您的遊標在哪裡。

現在,SSH 客戶端其實並不知道這些 ANSI 轉義碼的意思。對於 SSH 來說,它們都只是從標準輸入讀取的字元。<ENTER>~CSSH 客戶端看到的不是 ,而是<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(等待連線終止時)
~? - 此訊息
~~ - 透過鍵入兩次來發送轉義字元
(請注意,轉義字元僅在換行符之後立即被識別。)

相關內容