在没有-tt的情况下stderr的ssh缓冲存在问题



我正在尝试使用ssh远程运行bash脚本,该脚本将两者都输出到stderr和stdout
当我在终端中正常运行时,我会按顺序获得输出。但是当使用ssh运行我不使用,例如:

$ ssh -T user@host bash <<< "echo hi >&2 && echo bye"
bye
hi

stderr被延迟到stdout之后。这与大多数我在网上看到的关于缓冲stderr和stdout表示stderr未缓冲(因此将首先输出(。

但不管怎样,我尝试的几乎所有操作都无法将行输出整齐我试过把stdbuf-e0-o0-i0打到几乎每个命令的一部分(在ssh之前、bash之前、echo之前(。我尝试了不同的方式来传递命令(使用CCD_ 1,根本没有CCD_ 2(。

我发现有一种方法似乎一直有效,那就是将-tt传递给ssh。但是使用-tt似乎增加了它自己的蠕虫罐头,并且如果可能的话,我宁愿不去。

有没有其他方法可以让ssh输出缓冲更"有效";正常";?

stderr未缓冲仅表示数据立即写入fd,但不能保证写入的数据何时由接收器处理(pty、socket、pipe…(。

对于ssh -T,请参见以下示例(在Debian Linux上(:

[STEP 103] # ssh -T 127.0.0.1 'ls -l /proc/$$/fd'
total 0
lr-x------ 1 root root 64 Aug  4 13:59 0 -> pipe:[4610144]
l-wx------ 1 root root 64 Aug  4 13:59 1 -> pipe:[4610145]
l-wx------ 1 root root 64 Aug  4 13:59 2 -> pipe:[4610146]
lr-x------ 1 root root 64 Aug  4 13:59 3 -> /proc/23662/fd
[STEP 104] #

如图所示,sshd使用3个管道与其子进程进行通信(通过这种方式,sshd能够区分stdout数据和stderr数据(。对于子进程,可以保证写入stderr的数据将立即发送到管道,但何时处理数据完全取决于sshd进程。(UPDATE:即使在sshd将数据发送回ssh客户端之后,它仍然由ssh客户端决定何时处理接收到的数据。(

对于bash -c0,将为子级分配一个pty。子进程的stdin、stdout和stderr都将在pty上打开,sshd无法区分stdour数据和stderrs数据,因此结果是意料之中的。


验证ssh -tt无法区分stdout数据和stderr数据:

[STEP 109] # ssh -T 127.0.0.1 'echo hi; echo bye >&2'
hi
bye
[STEP 110] # ssh -T 127.0.0.1 'echo hi; echo bye >&2' 2> /dev/null
hi
[STEP 111] #
[STEP 112] # ssh -tt 127.0.0.1 'echo hi; echo bye >&2'
hi
bye
Connection to 127.0.0.1 closed.
[STEP 113] # ssh -tt 127.0.0.1 'echo hi; echo bye >&2' 2> /dev/null
hi
bye
[STEP 114] #

最新更新