Eu sei o que
program > /dev/null 2>&1
faz. Ele redireciona a saída para /dev/null
e 2>&1
significa redirecionar a saída de erro no mesmo lugar para onde a saída é enviada.
Meu problema é que sempre tenho que pesquisar no Google porque nunca me lembro.
Então, eu tento &2>1
, 1>2&
, 1>&2
... Eu tento todas as combinações até pesquisar no Google ...
Qual é o truque para lembrar facilmente?
A saída é melhor do que o erro, por isso vem primeiro (1 contra 2).
>
é uma abreviação de 'vai para'. À esquerda está o que eu quero enviar e à direita está para onde eu quero enviar. Uma vez que 'onde' é (quase) sempre um arquivo, algo como
program > /dev/null 2>1
redirecionaria para um arquivo chamado 1. Assim, o e comercial (&)
modifica o arquivo para o descritor de arquivo.
Infelizmente, não encontrei nem desenvolvi meu próprio mnemônico, mas quando estava aprendendo * nix pela primeira vez, descobri essa maneira lógica de funcionar bem. Depois de algumas passagens, torna-se uma segunda natureza.
Um truque é lembrar que 1 = saída padrão, 2 = erro padrão. Assim:
2>&1
= fluxo de erro padrão vai para fluxo de saída padrão.1>&2
= vice-versa.
Se você já programou em uma linguagem semelhante a C, é fácil lembrar o e comercial (&
). Eu escolho pensar nisso como se referindo ao "endereço do" descritor de arquivo existente, para que você não altere o próprio arquivo ou crie um novo.
Vendo o &
como um nó pode ajudar: pense no que você quer fazer tomando a saída de 2, então 2>
, e amarrando-o com 1, então 2>&1
Vamos considerar estas três opções:
program 2>1
program 2>1&
program 2>&1
O primeiro envia stderr para um arquivo denominado "1": afinal, o bash espera redirecionar para um arquivo.
O segundo também redireciona para o mesmo arquivo, mas executa program
em segundo plano: isso é o que um &
deve significar.
Isso deixa a terceira possibilidade como a única que faz sentido no universo do bash para redirecionar para um identificador de arquivo.
Como lembrar qual é qual entre 0, 1, 2? Pense em executar um computador a partir do console. Primeiro, você deve digitar algo (0 = stdin). Então, você vê a saída (1 = stdout). Por último, e somente se algo der errado, você verá stderr (2).
Na verdade, depende de qual Shell você está usando. O Bash costuma perdoar e você pode apenas fazer:
program &> file
Desenhe no seu papel de parede.
Agora, falando sério, essas e outras coisas básicas eu sempre esquecia, então adicionei um menu de dicas rápidas a um aplicativo que desenvolvi e que uso diariamente. Você pode querer tentar ou usar algo como o gnote para manter uma nota.
Em relação ao bash Shell, acho que a melhor maneira de lembrar é entendendo o que está acontecendo.
Se tudo que você quer fazer é lembrar como acertar o comando, você pode tentar
program > /results 2> /results
Isso é bom e óbvio o que está acontecendo e fácil de lembrar. ou seja.
1
STDOUT vai para /results
2
STDERR também vai diretamente para /results
o problema é que isso não funciona como você esperava. considere o seguinte:
arquivo: /tmp/poem.txt
the quick brown fox jumped over the lazy dog
e executar o comando
grep "brown" /tmp/poem.txt NOT_A_FILE > /tmp/results 2> /tmp/results
então
$ cat /tmp/results
grep: NOT_A_FILE: No such file or directory
lazy dog
o que aconteceu aqui?
Meu entendimento é bash configurar o redirecionamento apontando o STDERR diretamente para o arquivo /tmp/results
e devido à natureza de >
que faz 2 coisas
>>
faz.Portanto, neste caso STDERR, é inserido diretamente no início de /tmp/results
substituindo a saída de STDOUT.
Observação: se você usou >>
para anexar, você provavelmente conseguirá usar essa sintaxe.
No entanto, para corrigir o problema, você precisa - não redirecionar STDERR - para o arquivo diretamente, mas sim mesclar a saída de STDERR no STDOUT fluxo, para que você não tenha uma colisão.
Usando o operador 2>&1
operador consegue isso
grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1
O &
permite que o bash se diferencie de um arquivo chamado 1
e a 1
descritor de arquivo.
Para mim, a declaração 2>&1
em si explica exatamente o que está acontecendo - STDERR está sendo redirecionado para o próprio STDOUT - e termina apenas em /tmp/results
porque é para onde STDOUT está apontado (quase como um efeito colateral).
Ao contrário do que muitos guias afirmam, que é que 2>&1
envia STDERR para onde STDOUT está apontado. Se isso fosse verdade, você ainda teria o problema de substituição.
Para obter mais informações, consulte - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection
Ler 2>&1
como redirecionar stderr (2), para onde stdout (1) está atualmente indo.
À medida que lemos (e é processado) da esquerda para a direita. A leitura correta de >file 2>&1
direciona o stdout para o arquivo e, a seguir, direciona o stderr para o mesmo lugar que o stdout está indo agora.