I'm playing around with xinput to watch keyboard events.
I'd like to transform the output with awk and pass it to tee, printing to stdout and writing to a file simultaneously.
I watch events on device 14, type a single Space, then type Ctrl+C to exit:
$ xinput test 14
key release 36
key press 65
key release 65
key press 37
key press 54
^C
I can transform this with awk:
$ xinput test 14 | awk '{ print $NF }'
36
65
65
37
54
^C
Or I can pipe it to tee:
$ xinput test 14 | tee a.log
key release 36
key press 65
key release 65
key press 37
key press 54
^C
$ cat a.log
key release 36
key press 65
key release 65
key press 37
key press 54
But I can't pipe the transformed output to tee:
$ xinput test 14 | awk '{ print $NF }' | tee b.log
^C
$ cat b.log
I think I understand what's going on, and can boil it down to a simpler example where I cat stdin to tr and pipe that to tee.
$ cat | tr a x | tee x.log
If I type A B Enter, then Ctrl+C, the pipeline aborts before printing to stdout or writing to x.log (though the file itself is created):
ab
^C
$ cat x.log
If I type Ctrl+D instead of Ctrl+C, an EOF character signals the end of input, and output gets printed to stdout and written to x.log:
ab
xb
$ cat x.log
xb
I've tried a couple different approaches, but so far no success.
$ { xinput test 14 | awk '{ print $NF }' ; } > >(tee x.log)
$ exec {fd}> >(tee x.log)
$ xinput test 14 | awk '{ print $NF }' >& ${fd}
$ exec {fd}>&-
$ exec > >(tee x.log)
$ xinput test 14 | awk '{ print $NF }'
Can this be done?