sed 在管道传输时无法正常工作

sed 在管道传输时无法正常工作

由于某种原因,当将 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

相关内容