linux + 为什么命令输出不能被过滤或保存在文件中

linux + 为什么命令输出不能被过滤或保存在文件中

clockdiff是测量主机之间时钟差异的命令

这是来自我的 Linux 机器的示例。

clockdiff -o 162.23.2.2
.
host=server11 rtt=750(187)ms/0ms delta=0ms/0ms Tue Oct 24 11:01:42 2023

问题是当我们想要过滤输出或将输出保存到文件时,如下所示

clockdiff -o 162.23.2.2 >/tmp/file

more /tmp/file

1698145574 0 0

正如我们上面看到的,文件的输出不是我们从控制台运行命令时的输出

关于如何保存输出的任何想法如下:

.
host=server11 rtt=750(187)ms/0ms delta=0ms/0ms Tue Oct 24 11:01:42 2023

答案1

clockdiff检测其 stdout 是否为终端设备,在这两种情况下,其输出格式不同。这类似于工具的行为,例如,自动为输出到终端的颜色,但在写入管道或常规文件时忽略颜色代码(例如 GNU lswith --color=auto)。的行为clockdiff在机制上相似,但相当疯狂;正如您所发现的,它远远超出了“外观”,两种情况下的输出有很大不同。

该(错误)功能尚未记录在案;或者至少我还没有找到记录。如果有选项可以关闭该(错误)功能,那么也没有记录在案。

忽略所有怀疑 stderr 或您重定向到的文件存在问题的评论和假设。我已经在我的 Debian 12 中进行了测试clockdiffiputils 20221126它的行为取决于独自stdout 是否是终端。

要将终端中看到的内容保存到常规文件中,你需要使用 trick clockdiff。请阅读如何欺骗命令,让其认为其输出将发送到终端。该链接指向我们姊妹网站上的一个已建立的问题;如果它崩溃,它将与整个 Stack Exchange(包括超级用户)一起崩溃,因此无需在此重复所有内容。下面是从链接问题的选定答案中收集的可能工具列表。有关详细信息,请参阅这些答案。

可能的工具:

  • ptybandage

  • unbuffer– 我已经测试过了clockdiff,这是一个解决方案:

    unbuffer clockdiff -o 162.23.2.2 >/tmp/file
    
  • script– 也经过测试,这是一个解决方案(但script会向文件添加页眉和页脚;甚至它的(回显的)输入,因此从中获取输入</dev/null是个好主意):

    </dev/null script -qc 'clockdiff -o 162.23.2.2' -O /tmp/file
    
  • socatpty选项– 这个我也测试过了,是一个解决方案:

    socat -u EXEC:'clockdiff -o 162.23.2.2',pty STDOUT >/tmp/file
    
  • 与使用的自定义共享库LD_PRELOAD– 也经过测试,这是一个解决方案(并注意,如果您愿意,sudo clockdiff …那么LD_PRELOAD=… sudo clockdiff …可能不会起作用,而sudo LD_PRELOAD=… clockdiff …可能起作用;但这一切都取决于政策)。

笔记:

  • 这些工具中的大多数都是通过“欺骗命令,使其认为其输出将发送到终端”来实际上将其输出连接到为此目的专门创建的伪终端。该命令没有被欺骗,它获得了一个终端。这个LD_PRELOAD技巧才是真正的技巧。它让命令“认为”它的输出将到达一个终端,而没有提供终端。当被欺骗的命令试图对非终端的“终端”执行某些操作时,它可能会行为不当(例如,命令意外地获得了Inappropriate ioctl for device);但clockdiff在我的测试中表现良好。

  • 其中一些工具会自动将命令的 stderr 连接到与 stdout 相同的目标,因此两个流会合并(在您的情况下,它们都转到/tmp/file)。socat这个LD_PRELOAD技巧可以让您轻松区分 stdout 和 stderr clockdiff

相关内容