Bash 输出流写入文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9752291/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 01:48:07  来源:igfitidea点击:

Bash output stream write to a file

linuxbashshellubuntu

提问by mur

so i am running this on bash:

所以我在 bash 上运行这个:

# somedevice -getevent

What this command does is it just keeps running, and everytime my device sends a certain data, say it detects change in temperature, it outputs something like this

这个命令的作用是它只是继续运行,每次我的设备发送特定数据时,比如它检测到温度变化,它输出这样的东西

/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

And this just keeps running and as soon as it has any cause it outputs something. So there is no end to execution.

这只是继续运行,一旦有任何原因,它就会输出一些东西。所以执行是没有尽头的。

No the echo is working perfectly, however when i am trying to use the '>' operator this doesn't seem to write to file.

不,回声工作正常,但是当我尝试使用“>”运算符时,这似乎没有写入文件。

so for instance

所以例如

#somedevice -getevent > my_record_file

this doesn't work properly, my_record_file only gets data written to it in intervals, however i want to be written immediately.

这不能正常工作,my_record_file 只获取每隔一段时间写入的数据,但是我想立即写入。

Any ideas?

有任何想法吗?

回答by Adam Rosenfield

The output is being buffered because the C standard library changes the output buffering mode depending on whether or not stdout is a terminal device. If it's a terminal device (according to isatty(3)), then stdout is line-buffered: it gets flushed every time a newline character gets written. If it's not a terminal device, then it's fully buffered: it only gets flushed whenever a certain amount of data (usually something on the order of 4 KB to 64 KB) gets written.

输出被缓冲是因为 C 标准库根据 stdout 是否为终端设备更改输出缓冲模式。如果它是终端设备(根据isatty(3)),则 stdout 是行缓冲的:每次写入换行符时都会刷新它。如果它不是终端设备,那么它是完全缓冲的:只有在写入一定数量的数据(通常是 4 KB 到 64 KB 的数据)时才会刷新它。

So, when you redirect the command's output to a file using the shell's >redirection operator, it's no longer outputting to a terminal and it buffers its output. A program can change its buffering mode with setvbuf(3)and friends, but the program has to cooperate to do this. Many programs have command line options to make them line-buffered, e.g. grep(1)'s --line-bufferedoption. See if your command has a similar option.

因此,当您使用 shell 的>重定向运算符将命令的输出重定向到文件时,它不再输出到终端,而是缓冲其输出。一个程序可以setvbuf(3)和朋友一起改变它的缓冲模式,但程序必须合作才能做到这一点。许多程序都有命令行选项来使它们行缓冲,例如grep(1)'s--line-buffered选项。看看你的命令是否有类似的选项。

If you don't have such an option, you can try using a tool such as unbuffer(1)to unbuffer the output stream, but it doesn't always work and isn't a standard utility, so it's not always available.

如果您没有这样的选项,您可以尝试使用诸如unbuffer(1)对输出流进行缓冲的工具,但它并不总是有效并且不是标准实用程序,因此它并不总是可用。

回答by Roland Illig

The command somedeviceprobably uses the "Standard Input/Output Library", and in that library, the buffering is on by default. It is switched off when the output does to a terminal/console.

该命令somedevice可能使用“标准输入/输出库”,并且在该库中,默认情况下缓冲是打开的。当输出到终端/控制台时它被关闭。

Can you modify the somedeviceprogram? If not, you can still hack around it. See http://www.pixelbeat.org/programming/stdio_buffering/for details.

你能修改somedevice程序吗?如果没有,你仍然可以绕过它。有关详细信息,请参阅http://www.pixelbeat.org/programming/stdio_buffering/

回答by je4d

This is probably because your "somedevice -getevent" command's stdout is being block-buffered. According to this, stdout is by default line-buffered (i.e. what you want) if stdout is a terminal, and block-buffered otherwise.

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

I'd have a look at the manual for your somedevicecommand to see if you can force the output to be unbuffered or line-buffered. If not, stdbuf -oL somedevice -getevent > my_record_fileshould do what you want.

我会查看您的somedevice命令的手册,看看您是否可以强制输出无缓冲或行缓冲。如果没有,stdbuf -oL somedevice -getevent > my_record_file应该做你想做的。

回答by JScoobyCed

You can try 'tee':

你可以试试'tee':

somedevice -getevent | tee -a my_record_file

The '-a' option is to append instead of just replacing the content.

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