将过滤后的 redis-cli 输出保存到文件

Saving filtered redis-cli output to a file

我正在尝试查找刷新缓存的时间和方式,计划为此使用命令 redis-cli monitor | grep -iE "del|flush" > redis_log.txt,但由于某种原因文件为空。如果我使用不带 > redis_log.txt 部分的命令 - 它在终端中显示正确的输出,如果我使用 redis-cli monitor > redis_log.txt 命令 - 它也会将实际输出保存到文件中,但一起失败,只有一个空的文件被创建。有人遇到过类似的问题吗?

如评论中所述,您注意到的问题肯定来自应用于 grep 命令的 I/O 缓冲,尤其是当其标准输出未附加到终端,而是重定向到一个文件左右。

更准确地说,参见例如this nice blog article 最后总结一下:

Here’s how buffering is usually set up:

  • STDIN is always buffered.
  • STDERR is never buffered.
  • if STDOUT is a terminal, line buffering will be automatically selected. Otherwise, block buffering (probably 4096 bytes) will be used.

[…] these 3 points explain all “weird” behaviors.

一般解决方案

要调整程序的 I/O 流缓冲,coreutils 提供的一个非常方便的程序是 stdbuf

因此对于您的用例:

  • 您可能希望将 grep -iE "del|flush" 替换为:
    stdbuf -o0 grep -iE "del|flush" 完全禁用 STDOUT 缓冲;
  • 或者如果您想要一些权衡并且只使用 STDOUT 行缓冲,
    您可能希望将 grep -iE "del|flush" 替换为:
    • 或者stdbuf -oL grep -iE "del|flush"
    • grep --line-buffered -iE "del|flush".

总结

最后 by @jetchisel,您可能还想将 STDERR 重定向到您的日志文件,以免错过一些错误消息……因此,例如:

redis-cli monitor | stdbuf -o0 grep -iE "del|flush" > redis_log.txt 2>&1