我正在尝试使用此命令监视主题更改:
dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" | grep -o "uint32 ."
。现在的输出如下所示:
uint32 0
uint32 0
uint32 1
uint32 1
uint32 0
uint32 0
uint32 1
uint32 1
此输出来自主题切换。由于某种原因,主题通知出现了两次。现在我想将它通过管道传输到uniq
,所以我只保留一个条目,如下所示:
uint32 0
uint32 1
uint32 0
uint32 1
uniq
但是,最后
追加不再产生任何输出。dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" | grep -o "uint32 ." | uniq
来自man uniq
:
从 INPUT(或标准输入)中过滤相邻的匹配行,写入 OUTPUT(或标准输出)。
uniq
至少需要缓冲最后一条输出线才能检测到相邻的线,我看不出有任何理由不能缓冲它并沿着管道传递它。我已经尝试按照此处的建议调整行缓冲,但结果对我来说仍然相同。
dbus-monitor --session "interface='org.freedesktop.portal.Settings', member=SettingChanged" | grep -o "uint32 ." | stdbuf -oL -i0 uniq
这是许多工具的通常行为(可能是因为这种行为实际上是在共享库中构建的):当它们检测到输出是终端时,它们使用行缓冲模式。当他们检测到输出不是终端时,他们会缓冲更多,以提高吞吐量。
这里的相关命令不是
uniq
,而是grep
因为它的输出从终端切换到非终端。GNUgrep
有一个选项可以改变这种行为--line-buffered
::如果命令没有选择行为的特定选项,仍然可以使用
stdbuf
通过机制改变行为的命令LD_PRELOAD
。要恢复不在管道末尾的命令的行为,可以在该命令前加上前缀stdbuf -oL
。所以对于OP的情况:
或者如果此
grep
命令也没有特定选项:请注意,在这两种情况下,
uniq
位于管道的末端不需要对其默认行为进行任何调整。如果稍后管道被扩充并且
uniq
不再处于末端并且因此不再输出到终端,它也会受到影响并且需要相同的处理。例如行为的改变:对以下行为:
可以通过以下方式逆转: