Quais são as diferenças entre & e 2 & 1

23

Existem duas formas de redirecionamento da saída padrão e erro padrão na saída padrão . Mas qual é o melhor? e porque o &> é considerado o perfeito?

Eu não consigo encontrar quais são as diferenças, de modo que muitos tutoriais e até mesmo o estado manual bash que &> é melhor!

Então, por que devo usar &> e não 2>&1

Principalmente usando bash shell

EDIT: Obrigado por comentaristas

Apenas > & amp; funciona em csh ou tcsh

Em ksh, apenas 2 > & 1 funciona.

traço use > arquivo 2 > & 1 somente redirecionamento

Então qual deles usar para garantir que meu script seja compatível com outros sistemas, quaisquer que sejam os shells usados!

    
por Maythux 11.06.2015 / 12:30

4 respostas

19

A página man do Bash menciona que há duas maneiras de redirecionar stderr e stdout : &> file e >& file . Agora, observe que ele diz stderr e stdout.

No caso deste >file 2>&1 , estamos fazendo o redirecionamento do stdout (1) para o arquivo, mas também dizendo ao stderr (2) para ser redirecionado para o mesmo local que o stdout! Então o propósito pode ser o mesmo, mas a ideia é um pouco diferente. Em outras palavras, "John, vá para a escola; Suzzie vá para onde John for".

E quanto a preferência? &> é uma coisa bash . Então, se você estiver portando um script, isso não será feito. Mas se você está 100% certo de que seu script estará trabalhando apenas no sistema com o bash - então não há preferência

Aqui está um exemplo com dash , o Debian Amquist Shell, que é o padrão do Ubuntu.

$ grep "YOLO" * &> /dev/null
$ grep: Desktop: Is a directory
grep: Documents: Is a directory
grep: Downloads: Is a directory
grep: Music: Is a directory
grep: Pictures: Is a directory
grep: Public: Is a directory
grep: Templates: Is a directory
grep: Videos: Is a directory
grep: YOLO: Is a directory
grep: bin: Is a directory

Como você pode ver, o stderr não está sendo redirecionado

Para resolver suas edições na pergunta, você pode usar a instrução if para verificar a variável $ SHELL e alterar os redirecionamentos de acordo

Mas, para a maioria dos casos, > file 2>&1 deve funcionar

Em termos mais técnicos, o formulário [integer]>&word é chamado de Duplicando o Descritor do Arquivo de Saída , e é um recurso especificado pelo padrão POSIX Shell Command Language, que é suportado pela maioria dos shells compatíveis com POSIX e tipo Brourne.

Veja também O que & amp; significa exatamente no redirecionamento de saída?

    
por Sergiy Kolodyazhnyy 11.06.2015 / 12:50
5

Eu geralmente recomendo seguir a maneira de fazer o Borne SHell, já que o bash é indiscutivelmente o shell Unix mais popular por aí. Bash normalmente usa &> ou 2>&1 . IMHO, nem é "perfeito", então eu recomendo esquecer esse absurdo. Realisticamente, qual você deve usar depende do que você está tentando fazer.

2>&1 mescla stderr com stdout, o que pode ser útil se, por exemplo, você quiser enviar texto stderr. Então, por exemplo, se você quiser ver se um programa imprime uma determinada mensagem stderr, mas não quer que sua tela seja preenchida com lixo (presumivelmente) sem importância, você poderia fazer algo como program 2>&1 | grep crashed , que pesquisará o stdout e stderr de um programa chamado "programa" para a palavra "caiu".

Por outro lado, se você não quer que um programa imprima nada, você pode simplesmente executar program &> /dev/null , que irá redirecionar stderr e stdout para / dev / null, um arquivo especial que magicamente faz as coisas desaparecer. Ou, se você quiser salvar a saída de um programa (talvez para relatar um bug ou algo assim), você pode redirecionar stderr e stdout para um arquivo: program &> log.txt irá redirecionar todos os dados para um arquivo chamado "log.txt". Se você quisesse, poderia redirecionar a stdout e stderr via program 2> log.txt > log.txt ou program 2>&1 | cat > log.txt , e ambas teriam o mesmo efeito de usar &> . Se você fizer algo como program 2>&1 > file , somente o stdout será redirecionado, mas o stderr ainda pode ser canalizado para outro programa, como o cat, que pode ser redirecionado como mostrado acima. No entanto, digitar &> é mais fácil do que qualquer um dos exemplos acima, pois envolve digitar menos caracteres (e é um pouco mais fácil para os seres humanos lerem). Observe que program 2> log.txt > log.txt pode ser mais propenso a trabalhar em shells não-bash.

PS: se você está preocupado com as pessoas usando outros shells, há algo que você pode adicionar na primeira linha do seu script chamado "magic number", ou "shebang". Isso é essencialmente uma forma de garantir que outros computadores (especialmente aqueles que executam sistemas operacionais semelhantes ao Unix) saibam qual programa usar para executar um script. Scripts diferentes usam shebangs diferentes. Um shebang para um script bash se parece com isso:

#!/bin/bash

Se você usar o acima como a primeira linha de um determinado script, o bash geralmente será usado para executar o dito script. Isso tornará muito mais difícil para alguém executar acidentalmente o script com o shell errado.

PS: Eu não vou mentir: até agora, eu não sabia que alguém poderia usar >& , mas, até onde o bash diz, parece fazer o mesmo que &> . Você aprende algo novo todos os dias.

    
por TSJNachos117 17.07.2016 / 03:37
4
% bl0ck_qu0te%

2>&1 é o shell padrão Bourne / POSIX.

&> é uma extensão bash e não de jure padrão.

Se você escrever scripts usando extensões bash, mais cedo ou mais tarde você vai encontrar falhas de scratch-head com mensagens de erro de sintaxe crípticas porque elas estão sendo executadas em um shell padrão.

    
por Stephen M. Webb 23.07.2016 / 05:17