Vi isso no topo do meu arquivo de script bash:
export LOGFILE=$LOGDIRECTORY/${SCRIPT_NAME}.log
exec > >(tee $LOGFILE)
exec 2>&1
O que isso faz? O que dois processos exec estão fazendo aqui? Percebo que, dessa maneira, toda a saída da execução do script é canalizada, $LOGFILE
mas eu queria entender da perspectiva das exec
declarações.
exec
linhas poderiam perfeitamente ser apenas uma (exec > >(tee "$LOGFILE") 2>&1
).Respostas:
Em shells,
exec
1) aberturas e redirecionamentos de arquivos 2) reaisexec
(substituindo a imagem do processo atual por outra imagem do processo).Estes
exec
s são redirecionamentos.Primeiro, você redireciona (
exec 1> >(tee $LOGFILE)
) ostdout
descritor (1) para um canal gerado por substituição de processo conectado a umtee
processo executado simultaneamente que tem$LOGFILE
como primeiro argumento e, em seguida, redireciona ostderr
descritor (2) para o mesmo local em que o descritor1
agora aponta (o tee tubo).Tendo em mente que os filedescriptors são herdados, você acabou de fazer com que todo o futuro
stdout
e astderr
saída passem para otee
processo, que os grava no$LOGFILE
e para onde quer que o filedescriptor 1 apontasse originalmente (provavelmente o seu terminal).Nota: O processo tee é enviado para o stdout original (= o editor de arquivo original 1) porque, como você pode aprender / pesquisar no bash (1) por expansão de comando simples e substituição de processo, a substituição do processo (
>()
<()
) acontece (junto com outras expansões) antes os redirecionamentos são executados, o que significa que o redirecionamentoexec 1> >(tee "$LOGFILE")
ocorre após otee
início, deixandotee
o mesmo editor de arquivo 1 que ele herdou do shell pai. (Se fosse o contrário,tee
seria feito para gravar em sua própria entrada, o que poderia torná-lo um impasse, dependendo do seu padrão de E / S).fonte