Como me lembro de como usar o redirecionamento?

40

Eu sei o que

  program > /dev/null 2>&1 

faz. Ele redireciona a saída para /dev/nulle 2>&1significa redirecionar a saída de erro no mesmo local para onde a saída é enviada.

Meu problema é que sempre preciso pesquisar no Google porque nunca me lembro.

Então, eu tento &2>1, 1>2&, 1>&2... I tentar todas as combinações até que eu google it ...

Qual é o truque para lembrá-lo facilmente?

Luc M
fonte
Eu tenho o mesmo problema, então faço isso da maneira "longa" - redirecione os dois program 1> /dev/null 2>/dev/null. Algumas vezes, porém, é necessário misturar o stdoute stderrjuntos para ver o que realmente está acontecendo - como a saída de um processo de compilação complexo sendo redirecionado para um arquivo. Nesse caso, acabo pesquisando no Google
ivanivan

Respostas:

20

A saída é melhor que o erro, por isso é a primeira (1 vs 2).

>é uma abreviação de 'vai para'. À esquerda é o que eu quero enviar e à direita é para onde eu quero enviar. Como 'where' é (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, eu não encontrei nem desenvolvi meu próprio mnemônico, mas quando eu estava aprendendo * nix, encontrei essa maneira lógica de funcionar bem. Após algumas análises, torna-se uma segunda natureza.

gvkv
fonte
Sua primeira frase não faz sentido para mim. stdouté o descritor de arquivo 1, stderré 2. Portanto, "error" vem antes de "output".
21810 Warren Young
Essa frase é um mnemônico para lembrar qual descritor de arquivo stdoute se stderrreferir.
gvkv
Ok, mas ainda parece confuso, já que a pergunta original é sobre tentar lembrar a ordem dos caracteres no encantamento "2> & 1".
Warren Young
9

Um truque é apenas lembrar que 1 = saída padrão, 2 = erro padrão. Tão:

2>&1= fluxo de erro padrão entra no fluxo de saída padrão.
1>&2= vice-versa.

Se você já programou em uma linguagem 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 arquivo em si ou crie um novo.

Thronic
fonte
7

Ver o &nó como um nó pode ajudar: pense no que você quer fazer, obtendo a saída de 2 2>, e amarrando-a com 1, então2>&1

Bertrand Lorentz
fonte
2
Eu apenas memorizei a frase "dois e um". Se seu mnemônico é uma frase ou um nó, ter um realmente ajudará.
Tim Kennedy
5

Na verdade, depende de qual shell você está usando. O Bash geralmente perdoa muito e você pode fazer:

program &> file
Kevin Cantu
fonte
5

Vamos considerar estas três opções:

program  2>1
program  2>1& 
program  2>&1

O primeiro envia stderr aos nomes de arquivos "1": afinal, o bash espera redirecionar para um arquivo.

O segundo também redireciona para o mesmo arquivo, mas é executado programem segundo plano: é isso que uma trilha &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 fim, e somente se algo der errado, você verá stderr (2).

John1024
fonte
1

Desenhe no seu papel de parede.

Agora, falando sério, esse e outras coisas básicas que eu continuava esquecendo, adicionei um menu de dicas rápidas a um aplicativo que desenvolvi e que uso diariamente. Você pode tentar ou usar algo como o gnote para manter uma nota.

Ubersoldat
fonte
1

Em relação ao shell bash, acho que a melhor maneira de lembrar é entender o que está acontecendo.
Se tudo o que você quer fazer é lembrar como obter o comando correto, tente

program > /results 2> /results

Isso é legal e óbvio e é fácil de lembrar. ie

  • 1 STDOUT vai /results
  • 2STDERR também vai diretamente para/results

o problema é que isso não funciona como você esperaria. considere o seguinte:

Arquivo: /tmp/poem.txt

the quick brown fox jumped over the lazy dog

e execute 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 setup o redirecionamento apontando o STDERR diretamente para o arquivo /tmp/resultse por causa da natureza do >que faz 2 coisas

  1. normalmente crie um novo arquivo - nesse caso, a oportunidade passou quando o bash passou dessa rotina no momento em que a saída é gerada.
  2. insira diretamente no início do arquivo. e não acrescentar como >>faz.

Portanto, neste caso, STDERR, insere diretamente no início da /tmp/resultssubstituição da saída de STDOUT.
Nota: se você costumava >>anexar, provavelmente poderia se safar dessa sintaxe.
No entanto, para corrigir o problema, você precisa - não redirecionar o STDERR - para o arquivo diretamente, mas mesclar a saída do STDERR no fluxo STDOUT, para não ter uma colisão.
O uso do 2>&1operador consegue isso

grep "brown" poem.txt NOT_A_FILE > /tmp/results 2>&1

O &permite bash para distinguir de um arquivo chamado 1eo 1descritor de arquivo.
Para mim, a 2>&1própria declaração explica exatamente o que está acontecendo - o STDERR está sendo redirecionado no próprio STDOUT - e só acaba /tmp/resultsporque é para onde o STDOUT é apontado (quase como um efeito colateral).
Ao contrário do que muitos guias afirmam, que 2>&1envia STDERR para onde quer que STDOUT seja apontado. Se isso fosse verdade - você ainda teria o problema de substituição.

Para mais informações, consulte - http://mywiki.wooledge.org/BashGuide/InputAndOutput#File_Redirection

the_velour_fog
fonte