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.