我正在使用命名管道来捕获系统日志消息。然后,我可以通过执行类似
的操作轻松查看syslogcat /var/log/local3.pipe | grep somefilter
or
grep somefilter /var/log/local3.pipe
这两个都很好地将syslogs输出到控制台。但是,如果我想将其捕获到文件中,我什么也得不到,例如
cat /var/log/local3.pipe | grep somefilter >> somefile.log
or
grep somefilter /var/log/local3.pipe >> somefile.log
文件始终保持为零字节。有谁知道为什么?我正在使用Red Hat Enterprise Linux 5.谢谢。
其他信息:对于想要在此重现此内容的人来说,这是完整的命令列表
su
<enter root password>
mkfifo /var/log/local3.pipe
chmod 644 /var/log/local3.pipe
echo "local3.* |/var/log/local3.pipe" >> /etc/syslog.conf
/etc/init.d/syslog restart
exit
然后使用一个ssh会话:
cat /var/log/local3.pipe
并在第二个ssh会话中(“测试它”应该在第一个ssh会话中显示
logger -p local3.info "Test it"
然后在第一个会话中将其更改为
cat /var/log/local3.pipe >> somefile.log
将更多日志发送到本地3(消息需要不同)。确认消息进入somefile.log
logger -p local3.info "Test it 2"
然后在第一个会话中将其更改为
cat /var/log/local3.pipe | grep -i test >> somefile.log
现在确认日志不会转到somefile.log
请注意,消息需要与上一条消息不同,否则记录器不会立即发送消息。
答案 0 :(得分:2)
我可以重现您的问题,这可以解决它:
cat /var/log/local3.pipe | grep -i --line-buffered test >> somefile.log
我认为原因是当标准输出引用终端(根据isatty(3)
)时,则使用行缓冲,但只要重定向到文件,libc就会切换到正常的固定大小缓冲。因此,在somefile.log
进程的标准输出缓冲区填满之前,您必须已经检查grep
,因此在它有任何理由写入文件之前。
强制行缓冲的另一种方法如下:
cat /var/log/local3.pipe | stdbuf -oL grep -i test >> somefile.log
您可以在这两篇精彩文章中详细了解所有这些内容:
(我很高兴地注意到stdbuf
是由今天通过电子邮件发送给我的关于完全不同的东西的小家伙写的 - 小世界!)