Como redirecionar o stderr para um arquivo [duplicado]

175

Enquanto usa nohup para colocar um comando para rodar em segundo plano, alguns dos conteúdos aparecem no terminal.

cp: error reading ‘/mnt/tt/file.txt’: Input/output error
cp: failed to extend ‘/mnt/tt/file.txt’: Input/output error

Eu quero salvar esse conteúdo em um arquivo.

    
por André M. Faria 18.05.2015 / 14:31

2 respostas

294

Existem dois fluxos de saída principais no Linux (e outros sistemas operacionais), saída padrão (stdout) e erro padrão (stderr). Mensagens de erro, como as que você mostra, são impressas com erro padrão. O operador de redirecionamento clássico ( command > file ) apenas redireciona a saída padrão, portanto, o erro padrão ainda é mostrado no terminal. Para redirecionar o stderr também, você tem algumas escolhas:

  1. Redireciona stdout para um arquivo e stderr para outro arquivo:

    command > out 2>error
    
  2. Redirecione stderr para stdout ( &1 ) e, em seguida, redirecione o stdout para um arquivo:

    command >out 2>&1
    
  3. Redirecionar ambos para um arquivo:

    command &> out
    

Para mais informações sobre os vários operadores de controle e redirecionamento, consulte aqui .

    
por terdon 18.05.2015 / 14:50
7

A primeira coisa a notar é que há algumas maneiras, dependendo do seu propósito e shell, portanto, isso requer um pequeno entendimento de vários aspectos. Mais típico, é via 2> em shells parecidos com o Bourne , como dash (que é um link simbólico para /bin/sh ) e bash ; primeiro é o shell padrão e compatível com POSIX e o outro é o que a maioria dos usuários usa para a sessão interativa. Eles diferem em sintaxe e recursos, mas felizmente para nós o redirecionamento de fluxo de erro funciona da mesma forma (exceto o &> não padrão). No caso do csh e seus derivados, o redirecionamento do stderr não funciona muito bem.

Vamos voltar para 2> part. Duas coisas importantes a serem observadas: > significa operador de redirecionamento, onde abrimos um arquivo e 2 integer significa descritor de arquivo stderr; na verdade, é exatamente assim que o padrão POSIX para a linguagem shell define o redirecionamento na seção 2.7 :

[n]redir-op word

Para o redirecionamento simples > , o 1 inteiro está implícito para stdout , ou seja, echo Hello World > /dev/null é igual ao echo Hello World 1>/dev/null . Observe que o operador inteiro ou de redirecionamento não pode ser citado, caso contrário, o shell não os reconhece como tal e, em vez disso, trata como uma cadeia de texto literal. Quanto ao espaçamento, é importante que o inteiro esteja ao lado do operador de redirecionamento, mas o arquivo pode estar ao lado do operador de redirecionamento ou não, ou seja, command 2>/dev/null e command 2> /dev/null funcionarão bem.

A sintaxe simplificada para o comando típico no shell seria

 command [arg1] [arg2]  2> /dev/null

O truque aqui é que o redirecionamento pode aparecer em qualquer lugar. Isso é tanto 2> command [arg1] quanto command 2> [arg1] são válidos. Observe que, para bash shell, existe &> maneira de redirecionar os fluxos stdout e stderr ao mesmo tempo, mas novamente - é bash específico e se você está se esforçando para a portabilidade de scripts, pode não funcionar. Veja também Ubuntu Wiki e Qual é a diferença entre & amp; > e 2 > & 1 .

Observação: O operador de redirecionamento > trunca um arquivo e sobregrava, se o arquivo existir. O 2>> pode ser usado para anexar stderr ao arquivo.

Se você perceber, > é destinado a um único comando. Para scripts, podemos redirecionar o fluxo de stderr de todo o script de fora como em myscript.sh 2> /dev/null ou podemos fazer uso de exec built-in . O exec built-in tem o poder de religar o fluxo para toda a sessão de shell, por assim dizer, seja interativamente ou via script. Algo como

#!/bin/sh
exec 2> ./my_log_file.txt
stat /etc/non_existing_file

Neste exemplo, o arquivo de log deve mostrar stat: cannot stat '/etc/non_existing_file': No such file or directory .

Ainda outra maneira é via funções. Como kopciuszek observou em sua resposta, podemos escrever declaração de função com o redirecionamento já anexado, ou seja

some_function(){
    command1
    command2
} 2> my_log_file.txt
    
por Sergiy Kolodyazhnyy 03.05.2018 / 09:48