
我曾經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
)。