Порядок перенаправления

Я не совсем понимаю, как компьютер читает эту команду.

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

Если я понимаю, 2>&1 просто перенаправляет стандартную ошибку на стандартный вывод.

По этой логике команда читает мне следующее:

  1. объединить файлы file1 и file2 .

  2. отправьте stdout из этой операции в file.txt .

  3. отправьте stderr в stdout .

  4. конец?

Я не уверен, что делает компьютер. По моей логике, команда должна быть

cat file1 file2 2>&1 > file.txt

но это неверно.

Мне легче думать об использовании заданий.

  • > равно =
  • & похоже на $

Вы начинаете с

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

то ваш первый пример, 1> file.txt 2>&1 , делает

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

оставив вас

 1 = file.txt 2 = file.txt 

Если вы сделали это по-другому, снова вы начинаете с

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

то 2>&1 > file.txt

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

поэтому конечный результат

 1 = file.txt 2 = /dev/tty 

и вы только перенаправляете stdout , а не stderr .

Порядок перенаправления важен, и их следует читать слева направо .

Например: command 2>&1 >somefile означает:

  1. Переназначить stderr (а именно 2 ) в текущий пункт назначения stdout (в этот момент, терминал).
  2. Затем измените stdout чтобы перейти к somefile .

Таким образом, в этом случае stderr отправляется на терминал, а stdout переходит к файлу, чего вы, скорее всего, не хотите.

С другой стороны, command >somefile 2>&1 означает:

  1. Перенаправить stdout в somefile
  2. Затем перенаправьте stderr в тот же пункт назначения, что и stdout ( somefile ).

В этом последнем случае stderr и stdout переходят в некоторый somefile , который, вероятно, вы хотите.

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

>& На самом деле означает дубликат, он использует системный вызов dup для сопоставления нового дескриптора файла в уже открытом файле.

Итак, вы (bash на самом деле) должны сначала открыть новый stdout раньше, сказав «и перенаправить stderr на то, что в настоящее время установлено в stdout».