将过滤后的 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
我正在尝试查找刷新缓存的时间和方式,计划为此使用命令 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"
.
- 或者
总结
最后
redis-cli monitor | stdbuf -o0 grep -iE "del|flush" > redis_log.txt 2>&1