Redirecionar bash stdout + stderr para um arquivo e stderr para outro arquivo

4

Eu preciso redirecionar a saída ALL para um arquivo e, além disso, redirecionar o stderr para outro arquivo. Isso pode ser feito facilmente?

Vamos supor que meu comando para os propósitos deste exemplo seja:

php /tmp/doWork.php

Eu posso obter a saída para separar arquivos usando:

php /tmp/doWork.php 1> /tmp/stdout_file 2> /tmp/stderr_file

Com base no presente , tentei:

php /tmp/doWork.php &> /tmp/stdboth_file 2> /tmp/stderr_file

mas isso apenas coloca stdout e stderr em /tmp/stdboth_file e nunca escreveu para /tmp/stderr_file .

    
por Luke Cousins 10.05.2017 / 15:59

1 resposta

5

Com zsh (e zsh apenas) e seu recurso multios :

your-cmd 2> stdout+stderr.log >&2 2> stderr.log

Como o fd 2 é redirecionado duas vezes, zsh implementa um tee interno para que ele seja enviado para ambos os arquivos.

Com bash (ou qualquer shell parecido com o Bourne), você pode fazer o tee ing manualmente com:

{ your-cmd 2>&1 >&3 3>&- | tee stderr.log 3>&-; } > stderr+stdout.log 3>&1

(embora você perca o status de saída de your-cmd . zsh tem em $pipestatus[1] , bash in "${PIPESTATUS[0]}" embora (desde que o redirecionamento para stderr+stdout.log não tenha falhado)).

Para gravar o pid de your-cmd , você pode fazer:

{ sh -ec 'echo "$$" > /var/run/pidfile; exec your-cmd' 2>&1 >&3 3>&- |
   tee stderr.log 3>&-; } > stderr+stdout.log 3>&1

Com yash e o recurso redirecionamento de processo :

your-cmd > stdout+stderr.log 2>(tee stderr.log)

(mas note que yash não esperará o término do comando tee , então os arquivos de log podem não estar completos quando você executar o próximo comando depois disso).

Algo similar (e com a mesma limitação) pode ser feito com substituição de processo em bash , zsh e ksh93 :

{ your-cmd 2> >(tee stderr.log); } > stderr+stdout.log

Para ser executado em segundo plano e obter o pid:

(exec your-cmd 2> >(tee stderr.log)) > stderr+stdout.log & pid=$!

com rc :

{your-cmd |[2=0] tee stderr.log} > stdout+stderr.log
Os pipes de

rc permitem especificar quais descritores de arquivos estão conectados ao pipe. Com outros shells, é sempre fd 1 do comando esquerdo e fd 0 do direito (daí a pequena dança com o fd 3 acima para mudar os descritores de arquivo). rc reportará falha se your-cmd ou tee falhar, embora o número exato possa ser perdido.

    
por 10.05.2017 / 16:19