使用 ssh 传输时终端分配会破坏文件

mic*_*has 5 ssh pty

我曾经ssh使用以下方法解压远程文件:

ssh host "cat file.tgz" | tar xf -
Run Code Online (Sandbox Code Playgroud)

这工作得很好。但是我注意到在使用强制命令时,pty 分配会更改命令的输出:

ssh host -T "cat file.tgz" >first_file
ssh host -t "cat file.tgz" >second_file
Run Code Online (Sandbox Code Playgroud)

这里第一个文件很好,但第二个文件已损坏。

为什么 pty 的分配会改变输出?

Jak*_*uje 0

为什么 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|
Run Code Online (Sandbox Code Playgroud)

对我来说,区别仅在于0d 0a每个新行之前的两个字节,但可能还有更多(linux 行 Newline 仅是\n,但终端同时获取两者\r\n)。