Por que redirecionar a saída para 2 e 1 e 1 e 2?

29

Eu encontrei vários comandos que usam 2>&1 e 1>&2 , mas eu não consigo entender o propósito de usá-lo e quando devo usá-lo.

O que eu entendo

Eu sei que 1 representa saída padrão e 2 representa erro padrão. Entendo que 2>&1 combina a saída de 2 a 1 e vice-versa.

O que eu não entendo

  1. Quando devo usá-lo?
  2. Para que serve?
por PeanutsMonkey 14.06.2012 / 02:36

8 respostas

34

Às vezes, você quer redirecionar stdout e stderr para o mesmo local. É quando >& é usado - ele aponta um descritor de arquivo para outro.

Por exemplo, se você quiser gravar stdout e stderr no mesmo arquivo (seja /dev/null ou output.txt ), você pode redirecioná-los separadamente, com

app 1>/dev/null 2>/dev/null

ou você pode redirecionar um descritor de arquivo para o arquivo e o outro descritor de arquivo para o primeiro:

app 1>/dev/null 2>&1

app 2>/dev/null 1>&2

No primeiro exemplo, 2>&1 aponta o descritor de arquivo # 2 para onde # 1 já está apontando. O segundo exemplo é o mesmo, apenas começando com stderr.

Como outro exemplo, há casos em que stdout (descritor de arquivo # 1) já está apontando para o local desejado, mas você não pode se referir a ele pelo nome (pode estar associado a um pipe, um soquete ou outro). Isso geralmente acontece ao usar a expansão de processo (os operadores ' ' ou $( ) ), que normalmente só captura stdout, mas você pode incluir stderr nele. Nesse caso, você também usaria >& para apontar stderr para stdout:

out=$(app 2>&1)

Outro exemplo comum é um pager, ou grep , ou utilitário similar, já que o pipe | normalmente só funciona no stdout, você redirecionaria o stderr para stdout antes de usar o pipe:

app 2>&1 | grep hello

Como saber qual de 2>&1 ou 1>&2 está correto? O descritor de arquivo já configurado vai para a direita de >& , e o descritor de arquivo que você deseja redirecionar vai para a esquerda. ( 2>&1 significa "descritor de arquivo de ponto # 2 para o descritor de arquivo # 1".)

Algumas shells têm atalhos para redirecionamentos comuns; Aqui estão alguns exemplos do Bash:

  • 1> pode ser reduzido para apenas >

  • 1>foo 2>&1 a >&foo ou &>foo

  • 2>&1 | program a |& program

por 14.06.2012 / 02:59
2

Uma situação quando você precisa é quando você deseja exibir strace output em um pager. strace imprime sua saída para o padrão erro e os canais geralmente conectam a saída padrão à entrada padrão, então você tem que usar o redirecionamento:

strace -p $pid 2>&1 | less
    
por 14.06.2012 / 02:45
2

Às vezes, você deseja redirecionar os dois stdout ( 1 ) e stderr ( 2 ) para o mesmo local ( /dev/null , por exemplo). Uma maneira de conseguir isso seria:

$ program 1>/dev/null 2>/dev/null

Mas a maioria das pessoas encurta isso redirecionando stderr para stdout com 2>&1 :

$ program 1>/dev/null 2>&1

Uma versão ainda mais curta é:

$ program >&- 2>&-
    
por 27.07.2013 / 19:50
1

2: É para quando você terá saída de erro padrão e saída padrão, e você quer que eles sejam compostos em uma única string.

1: Quando você deseja manipular a saída do erro padrão e da saída padrão.

    
por 14.06.2012 / 02:41
0

Eu uso para iniciar um trabalho desanexado:

someProgram 2>&1 >& my.log &

então eu posso sair e algum programa ainda estará em execução. A funcionalidade é fornecida pelo GNU Screen, pelo tmux e por alguns outros programas - mas aqui ela é obtida sem nenhuma dependência externa.

    
por 27.07.2013 / 22:49
0

Imagine que existe um diretório chamado try que possui esses três arquivos: file file1 and file2.

Agora, execute este comando:

cat file file1 file2 file3

Os primeiros três arquivos são abertos, mas cat gera um erro ao abrir o quarto, pois não existe.

Agora execute:

cat file file1 file2 file3 1>outfile 2>&1

Você não verá nenhuma saída na tela: Em primeiro lugar, 1>outfile redirecionará a saída do comando para outfile e, em seguida, redirecionará ( 2>&1 ) o erro gerado ao tentar abrir file3 to outfile .

1>&2 funciona de maneira semelhante e redireciona o fluxo de erros para a saída padrão.

Espero que isso ajude!

    
por 16.09.2014 / 12:27
0

Alternative scenario: terminal commands show output into another terminal

Use o comando tty em cada terminal para identificá-los:

$ tty
/dev/pts/0

$ tty
/dev/pts/1

Assumindo que esses TTYs redirecionam o primeiro do stdout para o segundo, execute-o no primeiro terminal:

exec 1>/dev/pts/1

Note: Now every command output will show on pts/1

Para restaurar o comportamento padrão stdout de pts / 0:

exec 1>/dev/pts/0

Veja este vídeo para uma demonstração.

    
por 01.10.2017 / 06:51
0

O caso ao redirecionar stderr para stdout já foi coberto aqui (por exemplo, use-o para filtrar mensagens de erro (grep)).

O outro caso está redirecionando stdout para stderr. Um usecase comum (pelo menos para mim) é enviar avisos / mensagens de erro impressos com "echo" (em meus scripts) para o stderr (para que eles possam chamar a atenção do usuário mais facilmente).

Por exemplo,

echo "file \"${file\" does not exist..." 1>&2
    
por 14.06.2012 / 13:41