Leia stdin e passe pelo oleoduto para tee

1

Estou brincando com xinput para assistir a eventos de teclado. Gostaria de transformar a saída com awk e passá-la para tee , imprimindo para stdout e gravando em um arquivo simultaneamente.

Eu vejo eventos no dispositivo 14, digito um único Espaço , então digite Ctrl + C para sair:

$ xinput test 14
key release 36
key press   65
 key release 65
key press   37
key press   54
^C

Eu posso transformar isso com awk :

$ xinput test 14 | awk '{ print $NF }'
36
65
 65
37
54
^C

Ou posso canalizar para 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

Mas não posso canalizar a saída transformada para tee :

$ xinput test 14 | awk '{ print $NF }' | tee b.log
^C

$ cat b.log

Acho que entendo o que está acontecendo e posso resumi-lo em um exemplo mais simples em que eu cat stdin a tr e canalizar isso para tee .

$ cat | tr a x | tee x.log

Se eu digitar A B Enter , então Ctrl + C , o pipeline é anulado antes de imprimir para stdout ou gravar em x.log (embora o arquivo em si seja criado):

ab
^C

$ cat x.log

Se eu digitar Ctrl + D em vez de Ctrl + C , um caractere EOF sinaliza o fim da entrada, e a saída é impressa em stdout e gravada em x.log :

ab
xb

$ cat x.log
xb

Eu tentei algumas abordagens diferentes, mas até agora não tenho sucesso.

$ { 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 }'

Isso pode ser feito?

    
por ivan 18.02.2018 / 01:45

1 resposta

0

Eu encontrei duas soluções.

  1. Use stdbuf para executar awk sem buffer de saída.

    xinput test 14 | stdbuf -o0 awk '{ print $NF }' | tee b.log

  2. Adicione system("") call dentro do script awk

    xinput test 14 | awk '{ print $NF; system("") }' | tee b.log

por 18.02.2018 / 02:10

Tags