我正在尝试使用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 -c
0,将为子级分配一个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] #