Ssh

連接關閉時如何遠端終止稱為“tail -f”?

  • June 2, 2014

我剛剛注意到,如果我執行ssh user@remote_host tail -f /some/filetail -f /some/file即使 ssh 連接關閉,也會繼續在 remote_host 上執行!

因此,在多次連接和斷開連接後,執行次數tail -f /some/file會增加。tail -f關閉 ssh 連接時如何實際終止?

ssh host tail -f file

客戶端通過TCP 連接ssh連接到sshd伺服器。執行時將其標準輸出重定向到管道。讀取來自管道另一端的內容並將其封裝在 sshd 協議中以發送給客戶端。(使用,stdout 將直接是套接字,但添加了加密並且能夠在單個 TCP 連接上多路復用多個流(例如埠/代理/X11/隧道重定向,stderr),因此必須求助於管道)。host``sshd``tail -f``sshd``ssh``rshd``tail``sshd

當您按下 CTRL-C 時,會向ssh客戶端發送一個 SIGINT。這導致ssh死亡。死後 TCP 連接關閉。因此, onhost也會sshd死掉。tail沒有被殺死,但它的標準輸出現在是另一端沒有閱讀器的管道。因此,下次它向其標準輸出寫入內容時,它將收到一個 SIGPIPE 並死掉。

在:

ssh -t host 'tail -f file'

除了不是使用管道,而是通過偽終端進行通信之外sshd,這是同一件事。的 stdout 是一個從屬偽終端(如),主端的任何寫入(可能由 tty 行規則修改)由客戶端封裝並發送給客戶端。tail``tail``/dev/pts/12``tail``read``sshd``ssh

在客戶端,使用-tssh終端置於raw模式。特別是,這會禁用終端規範模式和終端信號處理。

因此,當您按下 時Ctrl+C,客戶端的終端線路規則不會向ssh作業發送 SIGINT,而是通過^C連接將字元發送到遠端終端的主端sshd並將其sshd寫入。^C並且遠端終端的線路規則發送SIGINTtailtail然後死掉,sshd退出並關閉連接並ssh終止(如果它不忙於埠轉發或其他)。

此外,-t如果ssh客戶端死亡(例如,如果您輸入~.),則連接將關閉並sshd終止。結果,一個 SIGHUP 將被發送到tail.

現在,請注意使用-t有副作用。例如,使用預設終端設置,\n字元被轉換為\r\n,並且可能會發生更多事情,具體取決於遠端系統,因此stty -opost如果該輸出不是用於的,您可能希望在遠端主機上發出(禁用輸出後處理)一個終端:

$ ssh  localhost 'echo x' | hd
00000000  78 0a                                             |x.|
00000002
$ ssh -t localhost 'echo x' | hd
00000000  78 0d 0a                                          |x..|
00000003
$ ssh -t localhost 'stty -opost; echo x' | hd
00000000  78 0a                                             |x.|
00000002

-t使用/的另一個缺點-tt是 stdout 和 stderr 在客戶端上沒有區別。遠端命令的 stdout 和 stderr 都將寫入ssh客戶端的 stdout:

$ ssh localhost ls /x  | wc -l
ls: cannot access /x: No such file or directory
0
$ ssh -t localhost ls /x | wc -l
1

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