【发布时间】:2014-05-19 22:30:34
【问题描述】:
我正在按照下面的代码 sn-p 运行脚本来跟踪日志文件。我遇到了一个问题,当几行几乎同时写入日志文件时,传递到 $line 的行从一开始就丢失了一些字节。
之后我可以检查文件,发现文件中的违规行是完整的,那么为什么它在脚本中不完整。可能是某种缓冲问题?
处理有时可能需要几秒钟才能完成,这会有所不同吗?
#!/bin/bash
tail -F /var/log/mylog.log | while read line
do
log "$line"
ffmpeg -i "from.wav" "to.mp3"
done
文件中的整行
"12","","765467657","56753763","test"
示例记录 $line
657","56753763","test"
更新 我已经对我的代码进行了更多调试,似乎导致问题的处理是对用于将 wav 转换为 mp3 的 ffmpeg 的调用。如果我只用睡眠交换它,那么问题就会消失。 ffmpeg 会以某种方式影响缓冲区吗?
【问题讨论】:
-
我的猜测是
tail通过一次调用write来写入整行,但这并不意味着管道缓冲区中有足够的空间来容纳整行,所以 shell必须丢弃一些东西来腾出空间。write似乎只有在启动时缓冲区已满时才会阻塞。 -
每行只有大约 300 字节,当一次只写入 3 或 4 行时会发生这种情况是否足以填满管道缓冲区?
-
嗯,可能不是。
ulimit -p建议bash可以将管道大小限制为 4096 字节,我认为 Linux 本身使用 64K(我使用来自 this answer 的脚本确认)。 -
尝试下一个:
tail -F /var/log/mylog.log | grep --line-buffered '.' | while ... -
ffmpeg在 while 循环中从 std 输入读取。为避免这种情况,请将 ffmpeg 的 std 输入重定向到另一个源,例如/dev/null,因此您的 ffmpeg 行如下所示:ffmpeg -i "from.wav" "to.mp3" < /dev/null