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

29

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

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

но это не правильно.

iDontKnowBetter
источник

Ответы:

46

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

  • > как =
  • & как $

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

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.

Mikel
источник
Я вроде получаю аналогию, но это сбивает с толку - что означает $стенд?
Элиран Малка
В назначении , как var=$othervar, $вводит имя переменной на правой стороне. В перенаправлении , как 2>&1, &вводит номер дескриптора файла , на правой стороне. Я говорю, что вы можете думать об этом как "файл 2 равен файлу 1". (Но есть два типа равных: <средства «для чтения» и >средства «для записи».)
Микел
12

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

Например: 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, что, вероятно , что вы хотите.

Амелио Васкес-Рейна
источник
4
cat file1 file2 1> file.txt 2>&1

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

Итак, вы (на самом деле bash) должны сначала открыть новый стандартный вывод, сказав: «и перенаправить стандартный поток вывода на любой установленный стандартный вывод».

X Тянь
источник
это круто! Мне было интересно об этом &. Не могли бы вы приложить некоторые ссылки на этот синтаксис или - еще лучше - некоторые хорошие ресурсы в вышеупомянутой системе dup?
Элиран Малка
1
'man dup' документирует системный вызов.
X Тиан
имеет смысл :) спасибо
Элиран Малка