It's just that when stdout is not a terminal, output is buffered.
And when you press Ctrl-C, that buffer is lost as/if it has not been written yet.
You get the same behavior with anything using stdio
. Try for instance:
grep . > file
Enter a few non-empty lines and press Ctrl-C, and you'll see the file is empty.
On the other hand, type:
xinput test 10 > file
And type enough on the keyboard for the buffer to get full (at least 4k worth of ouput), and you'll see the size of file grow by chunks of 4k at a time.
With grep
, you can type Ctrl-D for grep
to exit gracefully after having flushed its buffer. For xinput
, I don't think there's such an option.
Note that by default stderr
is not buffered which explains why you get a different behaviour with fprintf(stderr)
If, in xinput.c
, you add a signal(SIGINT, exit)
, that is tell xinput
to exit gracefully when it receives SIGINT
, you'll see the file
is no longer empty (assuming it doesn't crash, as calling library functions from signal handlers isn't guaranteed safe: consider what could happen if the signal comes in while printf is writing to the buffer).
If it's available, you could use the stdbuf
command to alter the stdio
buffering behaviour:
stdbuf -oL xinput test 10 > file
There are many questions on this site that cover disabling stdio type buffering where you'll find even more alternative solutions.
Best Answer
This supposed program will write to file descriptor number you specified. consider the following hello world program:
compile it
now a simple run
no file for 5, so no byte wrote.
next try:
I manage to get an output while specifying a file and a file descriptor (e.g.
5>u
).In practice, unless you have wrote such funny program as above, you are unlikely to collect data using
5>foo
.in shell script, construct using <( ) are more usefull: