我正在玩xinput
看键盘事件。我想使用 转换输出awk
并将其传递给tee
,打印到标准输出并同时写入文件。
我在设备 14 上观看事件,输入单个Space,然后输入Ctrl+C退出:
$ xinput test 14
key release 36
key press 65
key release 65
key press 37
key press 54
^C
我可以用以下方法来改变它awk
:
$ xinput test 14 | awk '{ print $NF }'
36
65
65
37
54
^C
或者我可以将其通过管道传输到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
但我无法将转换后的输出通过管道传输到tee
:
$ xinput test 14 | awk '{ print $NF }' | tee b.log
^C
$ cat b.log
我想我明白发生了什么,并且可以将其归结为一个更简单的示例,其中我将cat
stdin 传输到tr
并将其通过管道传输到tee
.
$ cat | tr a x | tee x.log
如果我输入A B Enter,然后输入Ctrl+ C,管道会在打印到标准输出或写入之前中止x.log
(尽管文件本身已创建):
ab
^C
$ cat x.log
如果我输入Ctrl+D而不是Ctrl+ C,则一个EOF
字符表示输入结束,并且输出将打印到 stdout 并写入x.log
:
ab
xb
$ cat x.log
xb
我尝试了几种不同的方法,但到目前为止没有成功。
$ { 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 }'
这可以做到吗?
答案1
我找到了两个解决方案。
用于在没有输出缓冲的情况下
stdbuf
运行。awk
xinput test 14 | stdbuf -o0 awk '{ print $NF }' | tee b.log
在脚本中添加
system("")
调用awk
xinput test 14 | awk '{ print $NF; system("") }' | tee b.log