Bash输出流写入文件

4

我现在在Bash上运行这个:

# somedevice -getevent

这个命令的作用是持续运行,每当我的设备发送某些数据时,比如检测到温度变化,它会输出类似于这样的内容。
/dev/xyz: 123 4567 8910112238 20
/dev/xyz: 123 4567 8915712347 19
/dev/xyz: 123 4567 8916412345 22
/dev/xyz: 123 4567 8910312342 25
/dev/xyz: 123 4567 8910112361 18
/dev/xyz: 123 4567 8910112343 20

这个程序会不断地运行,只要有任何原因它就会输出一些东西。因此,执行没有结束的时候。

不,echo命令运行得非常完美,但是当我尝试使用'>'操作符时,似乎无法将其写入文件。

例如:

#somedevice -getevent > my_record_file

这里出现了问题,my_record_file 只会在间隔时间内才能正常写入数据,但我希望数据可以立即写入。

您有任何想法吗?


延迟可能是由于输出缓冲引起的。您能否更改程序,在每次打印后执行flush()或在其标准输出上设置自动刷新? - Kyle Burton
好的,我找到了解决我的问题的方法,这是一个缓冲问题:somedevice -getevent | grep " " --line-buffered > myrecordfile 解决了这个问题...也许这不是最好的方法,但现在这个hack已经完成了工作...感谢你们的帮助! - mur
4个回答

5
输出被缓存是因为C标准库根据stdout是否为终端设备来更改输出缓冲模式。如果它是终端设备(根据isatty(3)),那么stdout是行缓冲的:每次写入换行符时都会刷新。如果它不是终端设备,则为全缓冲:只有在写入一定量的数据(通常为4 KB到64 KB)后才会刷新。
因此,当您使用shell的>重定向运算符将命令的输出重定向到文件时,它不再输出到终端并缓存其输出。程序可以通过setvbuf(3)和相关函数更改其缓冲模式,但程序必须配合使用。许多程序具有命令行选项,使它们成为“行缓冲”,例如grep(1)--line-buffered选项。请查看您的命令是否有类似的选项。
如果没有这样的选项,您可以尝试使用unbuffer(1)等工具来取消缓冲输出流,但它不总是有效,并且不是标准实用程序,因此并不总是可用。

2
命令somedevice可能使用“标准输入/输出库”,在该库中,缓冲默认开启。当输出到终端/控制台时,它会被关闭。
如果您无法修改somedevice程序,则仍然可以绕过它。有关详细信息,请参见http://www.pixelbeat.org/programming/stdio_buffering/

1
你可以尝试使用“tee”:
somedevice -getevent | tee -a my_record_file

'-a'选项是追加而不是仅替换内容。


0

这可能是因为您的“somedevice -getevent”命令的标准输出正在进行块缓冲。根据this,如果标准输出不是终端,则默认情况下是块缓冲(即您想要的),否则是行缓冲。

我建议查看一下您的somedevice命令手册,看看是否可以强制输出为无缓冲或行缓冲。如果不行,stdbuf -oL somedevice -getevent > my_record_file应该可以满足您的需求。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接