我用 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 -t
“igncr
忽略 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
$
更明智的做法是使用scp
或sftp
复制数据来消除(伪)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`