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.