使用 ssh 傳輸時終端分配會破壞文件

使用 ssh 傳輸時終端分配會破壞文件

我曾經ssh使用以下方法解壓縮遠端檔案:

ssh host "cat file.tgz" | tar xf -

這工作得很好。但是我注意到在使用強制命令時,pty 分配會更改命令的輸出:

ssh host -T "cat file.tgz" >first_file
ssh host -t "cat file.tgz" >second_file

這裡第一個文件很好,但第二個文件已損壞。

為什麼 pty 的分配會改變輸出?

答案1

它有助於閱讀ssh手冊頁:

 -T      Disable pseudo-tty allocation.                                     

 -t      Force pseudo-tty allocation.  This can be used to execute arbi‐    
         trary screen-based programs on a remote machine, which can be      
         very useful, e.g. when implementing menu services.  Multiple -t    
         options force tty allocation, even if ssh has no local tty.

當你告訴它分配A偽tty,遠端的任何進程都可以看到該連接是一個「真實」終端,並且由於該連接是互動式的,因此將發送附加訊息。在 shell 初始化中,它還可以設定終端模式,您可以使用 進行檢查stty -a。終端模式用於翻譯在鍵盤輸入和主機之間,以及從主機發送到終端的文字之間:

  • 沒有初始化時,連接不是終端,且不進行任何轉換。
  • 初始化時,終端機會將換行符號 ( \n) 轉換為回車換行符號 (0x0d、0x0a)。它還將(對於大多數用戶)將製表符轉換為空格。

所描述的效果是針對翻譯。沒有那個,你的互動的會話將“階梯”穿過螢幕並且無法使用。

您的 shell 也可能列印附加資訊,但對於單一命令,建議@kba 具有誤導性,因為 shell 通常不會發送提示,以及上述的 ssh 控制~C適用於輸入而不是輸出

當運行到終端機時,ssh 也會在關閉連線時列印一則訊息。但這被寫入標準誤差。

答案2

為什麼 pty 的分配會改變輸出?

因為遠端(具有分配的終端)將為您的本地終端“注入”控製字元(基本上是C0和C1控制碼)。由於您的本地端不是終端,而是文件,因此它只是將它們轉儲到該文件中。

SSH 正在盡力猜測您想要什麼(如果 stdin 不是 TTY,那麼它不會分配遠端 TTY,除非您添加-tt開關)。該選項的存在是有原因的,如果您想要二進位傳輸,您不希望終端弄亂您的檔案。

您只需傳輸小檔案然後十六進制轉儲即可看到此行為:

$ ssh -t host "cat test" > /tmp/test.t
$ ssh host "cat test" > /tmp/test
$ hexdump -C /tmp/test
00000000  0a 2a 20 46 72 69 20 46  65 62 20 31 32 20 32 30  |.* Fri Feb 12 20|
00000030  6d 3e 20 33 2e 34 2e 31  2d 31 0a 2d 20 4e 65 77  |m> 3.4.1-1.- New|

$ hexdump -C /tmp/test.t
00000000  0d 0a 2a 20 46 72 69 20  46 65 62 20 31 32 20 32  |..* Fri Feb 12 2|
00000030  6f 6d 3e 20 33 2e 34 2e  31 2d 31 0d 0a 2d 20 4e  |om> 3.4.1-1..- N|

對我來說,差異僅在於0d 0a每個新行之前的兩個字節,但可能還有更多(linux 行 Newline 僅是\n,但終端同時取得兩者\r\n)。

相關內容