由于某种原因,当将 SSH 的命令输出通过管道传输到 sed 时,我不会有实时输出:
ssh someuser@somehost 2>&1 | sed -e "s/\[32//g" | tee logging
我怀疑输出 dit 没有换行符,但是当我删除 sed 命令并运行时:
wc -l logging
它返回 6,这是正确的返回数。有人知道我在这里缺少什么吗?
[编辑]我完全忘记提及以下内容:运行
ssh someuser@somehost 2>&1 | sed -e "s/\[32//g"
返回所有值没有问题,但是,一旦我将 tee 添加到混合中,我将无法获得输出,直到我点击 ^C...甚至标准输出重定向都不起作用(ssh someuser@somehost 2>&1 | sed -e “s/[32//g”> 文件)。只需 ssh 和 tee 也可以正常工作。
答案1
流编辑器、sed、缓冲区,通过“-u”或“--unbuffered”禁用。
tail -f some/log_file | sed -u 's/foo//g' | grep bar
答案2
当您在没有显式命令的情况下运行时ssh user@somehost
,您将请求 ssh 在远程计算机上启动交互式 shell。
交互式 shell(例如 bash)通常希望有一个终端可用,因为它将使用终端命令来改善编辑命令行和浏览历史记录时的体验。 (终端命令允许全屏控制。)
但 ssh 默认情况下只会分配一个终端(也称为伪终端)如果其标准输出连接到终端。
如果您只是ssh user@somehost
从终端程序(例如 gnome-terminal、rxvt、xterm 等)运行,那么它的标准输出将是一个终端,因此 ssh 将创建一个伪终端,并且远程交互式 shell 将表现良好。
如果您通过某些东西(任何东西)(例如 )通过管道传输 ssh ssh user@somehost | cat
,那么它的标准输出将是一个管道(而不是终端),因此 ssh 将不会创建终端,这可能会使远程交互式 shell 行为异常。
一种可能的解决方案是强制 ssh 创建一个伪终端,方法是向其传递选项-t
,例如ssh -t user@somehost | cat
,可能帮助。 (此外,您可能需要一个双重选项-tt
来强制分配伪终端。)
另一种可能性是,如果您运行 ssh 主要是因为您对特定命令感兴趣,则可以从 ssh 命令行运行特定命令,例如ssh user@somehost mycommand | cat
.如果您运行特定命令,则不会涉及交互式 shell,在这种情况下,拥有可用的终端可能不会导致任何问题。
答案3
我会尝试使用相同的命令并添加以下内容:
ssh someuser@somehost 2>&1 | sed -e "s/\[32//g" | tee --output-error=warn logging
这样,您应该能够看到写入标准输出时是否有错误。让我知道这是否有帮助。
您可以安装expect,然后尝试:
unbuffer ssh someuser@somehost 2>&1 | sed -e "s/\[32//g" | tee logging