Erro padrão do tubo para arquivar e mantê-lo no erro padrão?

2

Eu tenho um script (fragmento) para o qual estou registrando a saída e o erro padrão:

#!/bin/sh
#...
{
   date "+%Y-%m-%d %T"
   cd $workdir
   ls -ltr validfile badfile #example command that provides stdout, stderr
} | tee -a $logfile

Se eu fizer o acima, obtenho o padrão no logfile. Para obter o erro padrão também, eu poderia fazer isso:

#!/bin/sh
#...
{
   date "+%Y-%m-%d %T"
   cd $workdir
   ls -ltr validfile badfile
} 2>&1 | tee -a $logfile

Mas esta versão em um script quando chamado na linha de comando não permite que eu analise erros:

$ ./script.sh 2>/dev/null

Simplesmente mostrará todos os erros padrão e padrão. E se, desta vez, eu quiser apenas desvendar os erros?

Você pode me mostrar como canalizar erro padrão para o log, mas deixá-lo no erro padrão para quando ele é chamado via linha de comando ou outro script?

AIX 7.1, ksh (sem bash)

    
por bgStack15 30.09.2014 / 22:38

1 resposta

3

Usando algum redirecionamento de saída sofisticado, é possível conseguir isso sem o redirecionamento básico do bash para processos.

Registrando erro padrão e mantendo-o no canal de erro padrão

#!/bin/sh
exec 4>&1    # important as it "saves" stdout (usually /dev/tty2 for example)
exec 3>&1    # work-in-progress file descriptor
logfile=/var/log/myscript.out

{
   {
      date "+%Y-%m-%d %T"
      cd $workdir
      ls -ltr validfile badfile
   } 2>&1 1>&3 | tee -a $logfile 1>&2 2>/dev/null 3>&4
} 3>&1 | tee -a $logfile

exec 4>&-   # proper form is to clean up when you're done
exec 3>&-

Explicação:% exec 4>&1 e exec 3>&1 criam novos descritores de arquivo 3 e 4, os quais apontam para qualquer saída padrão que esteja apontando para (seu terminal, provavelmente).

2>&1 redireciona o erro padrão de toda a chave de segundo nível para a saída padrão. 1>&3 redireciona o padrão para o que fd3 está apontando (que é padrão, mas não apenas no canal 1, que é significativo!)

| tee -a $logfile duplica o padrão in (vindo das chaves de segundo nível, portanto, o stderr antigo) para o arquivo de log e também para o padrão. 1>&2 move padrão para erro padrão (de volta para onde pertence) . 2>/dev/null provavelmente não é necessário, mas redireciona qualquer saída de erro do tee e trash dele. 3>&4 redireciona o pipe 3 para o pipe 4 (que, por acaso, está apontando para stdout, lembra?).

3>&1 pega o pipe 3 das chaves de primeiro nível e envia para saída padrão regular . | tee -a $logfile captura a entrada padrão (que é o padrão [ajustado] das chaves) e duplica para o log e para o padrão.

    
por 30.09.2014 / 22:38