Significado do redirecionamento '2>> (command)' no Bash

18

Há um tempo atrás, criei um script e adicionei alguns logs em torno dele, mas esqueci como o redirecionamento para o log funciona :-(

A essência disso é:

#!/bin/bash

LOGFILE=/some/path/mylogfile

(
  # here go my commands which produce some stdout
  # and, if something goes wrong, also some stderr
) 1>>${LOGFILE} 2> >( tee -a ${LOGFILE} >&2 )

Quando executo o script, ele não imprime nada stdout, mas apenas imprime o que é necessário stderr. O arquivo de log ${LOGFILE}captura o stdout e o stderr.

Quando executo o script e não há saída no meu terminal, sei que está tudo bem. Se houver alguma saída, sei que algo deu errado e posso verificar o arquivo de log para descobrir qual é o problema.

A parte do redirecionamento que agora me intriga é a sintaxe de: 2> >( some command )

Alguém pode explicar o que está acontecendo lá?

NZD
fonte

Respostas:

23

>(...)é chamado substituição de processo . Permite que o programa "externo" grave no programa "interno" como se fosse um arquivo.

Nesse caso, está escrevendo stderrao tee -a ${LOGFILE} >&2qual será anexado LOGFILEe, em seguida, também será gravado tudo de volta stderr.

O operador de redirecionamento pode ir em qualquer direção para a substituição do processo, para que você possa escrever nele, como neste exemplo, ou usá <(...)-lo para ler, o que é uma maneira útil de, por exemplo, fazer um whileloop sem executá-lo em uma subshell em si.

Eric Renouf
fonte
5
Entendi :-) Se eu executar echo <(date), dá-me o nome do arquivo substituído: /dev/fd/63. Se eu executar cat <(date), dá-me a data, ou seja, o conteúdo do arquivo substituído: Fri Nov 18 14:11:09 NZDT 2016.
NZD
@ NZD, sim - mas não imagine que seja um arquivo comum - o que você vê /devé um nome para o canal entre os processos.
Toby Speight
Esta técnica é usada porque o stderr não pode ser canalizado (para tee, neste caso)?
bli
@bli Sim, já que o stdout já está sendo redirecionado para outro lugar, isso me parece a maneira mais direta de teestderr e mantê-lo separado do stdout.
Eric Renouf 23/11