Bash 使用ffmpeg转换文件时,跟踪日志文件并处理每一行会丢失数据

Bash 使用ffmpeg转换文件时,跟踪日志文件并处理每一行会丢失数据,bash,shell,ffmpeg,tail,Bash,Shell,Ffmpeg,Tail,我正在按照下面的代码片段运行一个脚本来跟踪日志文件。我遇到了这样一个问题:当几行几乎同时写入日志文件时,传入$line的byline从一开始就丢失了大量字节 我可以检查文件后,看到有问题的行是完整的文件,那么为什么它是不完整的脚本。也许是某种缓冲问题 处理有时可能需要几秒钟才能完成,这会有什么不同吗 #!/bin/bash tail -F /var/log/mylog.log | while read line do log "$line" ffmpeg -i "from.wav"

我正在按照下面的代码片段运行一个脚本来跟踪日志文件。我遇到了这样一个问题:当几行几乎同时写入日志文件时,传入$line的byline从一开始就丢失了大量字节

我可以检查文件后,看到有问题的行是完整的文件,那么为什么它是不完整的脚本。也许是某种缓冲问题

处理有时可能需要几秒钟才能完成,这会有什么不同吗

#!/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"
更新
我对我的代码进行了更多的调试,似乎导致问题的处理是对ffmpeg的调用,该调用用于将wav转换为mp3。如果我用睡眠来交换,那么问题就消失了。ffmpeg会以某种方式影响缓冲区吗?

如果您所在的平台上有一个合理的最新版本(例如,任何相当新的Linux发行版),则可以使用强制行缓冲

中的示例非常相关:

 tail -f access.log | stdbuf -oL cut -d ' ' -f1 | uniq

这将立即在
中显示access.log中的唯一条目,同时
循环
ffmpeg
读取
std输入
,同时使用所有参数。为了防止这种行为,常见的解决方法是将
ffmpeg
std输入重定向到
/dev/null
,如下所示:

tail -F /var/log/mylog.log | while read line
 do
   log "$line"
   ffmpeg -i "from.wav" "to.mp3" < /dev/null
done
tail-F/var/log/mylog.log |读取行时
做
日志“$line”
ffmpeg-i“从.wav”到.mp3”

还有其他命令,例如
ssh、mplayer、HandBrakeCLI
…,它们在while循环中显示相同的行为

我的猜测是,
tail
只需一次调用
write
,就可以写出完整的行,但这并不意味着管道缓冲区中有足够的空间容纳整行,因此shell必须丢弃一些东西来腾出空间。如果缓冲区在启动时已完全满,
write
似乎只会阻塞。每行大约只有300字节,如果一次只写入3或4行,则会发生这种情况,这是否足以填充管道缓冲区?嗯,可能不会
ulimit-p
建议
bash
可能会将管道大小限制在4096字节,我认为Linux本身使用64K(通过中的脚本为我确认)。请尝试下一个:
tail-F/var/log/mylog.log | grep--line buffered.”而…
ffmpeg
在while循环中读取std输入。为了避免这种情况,将ffmpeg的std输入重定向到另一个源,比如说
/dev/null
,所以您的ffmpeg行看起来像:
ffmpeg-i“from.wav”“To.mp3”
这个“cut-dAQ…”让我困惑了一会儿,想知道这是否是一个未记录的“cut”黑客。此外,这个命令行在互联网上被广泛复制粘贴。事实证明,linux.die.net在将文本文档转换为HTML时有一个bug,而这些“aq”在手册的文本版本中曾经是单引号。然后,实际的例子是
tail-f access.log | stdbuf-oL cut-d'-f1 | uniq
,我真的不记得写过这个答案。我想我一定是没注意就复制粘贴了它。我只是去编辑了一下,现在看起来还不错。