为什么 ssh -t 选项在重定向输出中添加 cr 和 lf

为什么 ssh -t 选项在重定向输出中添加 cr 和 lf

我用 putty 从 windowsbox 连接到 linux box。之后我执行以下操作:

在服务器A上:

serverA: file /etc/motd
/etc/motd: : ASCII English text

在服务器B上:

serverB: ssh -t user@serverA "cat /etc/motd" > /etc/motd.serverA
serverB: file /etc/motd.serverA
/etc/motd.serverA:  ASCII text, with CRLF line terminators

为什么重定向后的输出现在有 CR 和 LF?仅当使用 ssh 的 -t 选项时才会发生这种情况。如果我需要使用 sudo 在 ssh 登录上运行命令,则需要 -t 。例如:

serverB: ssh -t user@serverA "sudo cat /etc/shadow" > /etc/shadow

感谢您的建议

答案1

检查 TTY 设置。

$ ssh -t somewhere 'stty -a' | grep cr
iflags: -istrip icrnl -inlcr -igncr -iuclc ixon -ixoff ixany imaxbel
oflags: opost onlcr -ocrnl -onocr -onlret -olcuc oxtabs -onoeot
cflags: cread cs8 -parenb -parodd hupcl -clocal -cstopb -crtscts -mdmbuf

这些可能会有所不同,但它们在这里显示,默认情况下,ssh -tigncr忽略 CR”在输入上被禁用,并且对于onlcr已设置的输出(将 NL 映射到 CR-NL),并且 CR 不会被破坏或省略。人们可以在手册中查找这些术语stty(1),也可以查看termios(4)(Linux 可能会将其放在其他一些 man 部分中)。

这些设置也可以修改(但这可能会破坏出于某种原因需要onlcr设置的东西):

$ ssh -t somehost 'stty onlcr; cat /etc/motd' > x ; file x
x: ASCII English text, with CRLF line terminators
$ ssh -t somehost 'stty -onlcr; cat /etc/motd' > x ; file x
x: ASCII English text
$ 

更明智的做法是使用scpsftp复制数据来消除(伪)tty CR/NL 处理导致文件内容更改的风险。

答案2

您用于强制 ssh 会话进行伪 tty 分配的选项-t会导致 STDOUT 进行行缓冲,因为(简而言之)shell 根据所告知的功能假定您正在使用交互式终端。

因此,输出以在交互式终端中有意义的方式传递。根据您在该 shell 中执行的操作以及环境的设置方式,如果您更仔细地查看数据,您甚至可能会看到颜色代码,它可能看起来像[^[0;32m].

Sudo 是一款旨在要求您输入密码的应用程序,因此需要 TTY。它希望能够影响终端功能,a) 要求您输入 STDOUT 的密码,b) 屏蔽您在 STDIN 上提供的输入,以免显示在 STDOUT 上。

因此,Sudo 需要-t-t行缓冲区输出,因此您会看到通常由终端本身解释的附加控制字符,而不是传递到 STDOUT。

答案3

您可以使用 dos2unix 实用程序来避免配置更改。我用过这种方法,它对我有用。

remote_hostname=`ssh -t ${sys_ip} 'uname -n'|dos2unix`

相关内容