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
You could make use of the builtin
compgen
:TAB at the prompt would list commands, shell builtins, keywords, aliases and functions. So you could say:
to get all the options that you see upon typing yTAB at the shell prompt into the file
myfile.txt
.Eliminate the
grep
pipeline in order to get all the possible commands, functions, ... into the file: