mur
mur

Reputation: 931

Bash output stream write to a file

so i am running this on 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.

Any ideas?

Upvotes: 4

Views: 9974

Answers (4)

je4d
je4d

Reputation: 7848

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.

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

Upvotes: 0

Adam Rosenfield
Adam Rosenfield

Reputation: 400692

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.

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-buffered option. See if your command has a similar option.

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.

Upvotes: 5

Roland Illig
Roland Illig

Reputation: 41686

The command somedevice probably 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.

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

Upvotes: 2

JScoobyCed
JScoobyCed

Reputation: 10423

You can try 'tee':

somedevice -getevent | tee -a my_record_file

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

Upvotes: 1

Related Questions