Ordem dos redirecionamentos

23

Eu não entendo muito bem como o computador lê esse comando.

cat file1 file2 1> file.txt 2>&1

Se eu entendi, 2>&1 simplesmente redireciona o erro padrão para a saída padrão.

Por essa lógica, o comando lê para mim da seguinte forma:

  1. concatene arquivos file1 e file2 .

  2. envie stdout desta operação para file.txt .

  3. envie stderr para stdout .

  4. final?

Não sei o que o computador está fazendo. Pela minha lógica, o comando deve ser

cat file1 file2 2>&1 > file.txt

mas isso não está correto.

    
por iDontKnowBetter 01.05.2012 / 00:28

3 respostas

35

Acho mais fácil pensar em usar atribuições.

  • > é como =
  • & é como $

Você começa com

1 = /dev/tty
2 = /dev/tty

então seu primeiro exemplo, 1> file.txt 2>&1 , faz

1 = file.txt
2 = $1           # and currently $1 = file.txt

deixando você com

1 = file.txt
2 = file.txt

Se você fez do outro jeito, novamente você começa com

1 = /dev/tty
2 = /dev/tty

então 2>&1 > file.txt faz

2 = $1           # and currently $1 = /dev/tty
1 = file.txt

para que o resultado final seja

1 = file.txt
2 = /dev/tty

e você redirecionou apenas stdout , não stderr .

    
por 01.05.2012 / 00:47
6

A ordem de redirecionamento é importante, e eles devem ser lidos da esquerda para a direita .

Por exemplo: command 2>&1 >somefile significa:

  1. Redirecione stderr (ou seja, 2 ) para o destino atual de stdout (neste ponto, o terminal).
  2. Em seguida, altere stdout para ir para somefile .

Portanto, neste caso, stderr vai para o terminal e stdout vai para um arquivo, o que você provavelmente não deseja.

Por outro lado, command >somefile 2>&1 significa:

  1. Redirecionar stdout para somefile
  2. Em seguida, redirecione stderr para o mesmo destino que stdout ( somefile ).

Neste último caso, tanto stderr como stdout vão para somefile , que é provavelmente o que você deseja.

    
por 28.12.2014 / 04:25
2
cat file1 file2 1> file.txt 2>&1

>& Na verdade significa duplicado, ele usa a chamada do sistema dup para mapear um novo descritor de arquivo em um arquivo já aberto.

Então, você (bash na verdade) deve primeiro abrir o novo stdout antes, dizendo "e redirecionar stderr para qualquer stdout que esteja definido atualmente."

    
por 08.11.2013 / 14:22