32

Что означает "2>&1"?

23

Я пытаюсь объединить потоки stderr и stdout в один поток stdout и применяю для этого следующий синтаксис к команде:

2>&1

Например, следующая команда позволяет мне увидеть несколько первых ошибок при компиляции файла main.cpp:

g++ main.cpp 2>&1 | head

Но что именно означает конструкция 2>&1?

5 ответ(ов)

36

Файловый дескриптор 1 — это стандартный вывод (stdout).

Файловый дескриптор 2 — это стандартная ошибка (stderr).

Сначала конструкция 2>1 может показаться хорошим способом перенаправить stderr в stdout. Однако на самом деле она будет интерпретироваться как "перенаправить stderr в файл с именем 1".

Символ & указывает, что то, что идет до и после, является файловым дескриптором, а не именем файла. Поэтому мы используем 2>&1. Рассматривайте >& как оператор слияния перенаправлений.

10

Чтобы перенаправить стандартный вывод (stdout) в файл file.txt, вы можете использовать следующую команду:

echo test > file.txt

Эта команда аналогична:

echo test 1> file.txt

Для перенаправления стандартного ошибок (stderr) в файл file.txt используйте:

echo test 2> file.txt

Синтаксис >& используется для перенаправления потока в другой дескриптор файла:

  • 0 — это stdin (стандартный ввод)
  • 1 — это stdout (стандартный вывод)
  • 2 — это stderr (стандартный вывод ошибок)

Для перенаправления stdout в stderr можно использовать следующую команду:

echo test 1>&2   # аналогично, можно записать как echo test >&2

Чтобы перенаправить stderr в stdout, выполните:

echo test 2>&1

Таким образом, в конструкции 2>&1:

  • 2> перенаправляет stderr в (неуказанный) файл.
  • &1 перенаправляет stderr в stdout.
1

Номера обозначают файловые дескрипторы (fd).

  • Ноль — это stdin (стандартный ввод)
  • Один — это stdout (стандартный вывод)
  • Два — это stderr (стандартный вывод ошибок)

2>&1 переадресовывает дескриптор 2 (stderr) в дескриптор 1 (stdout).

Это работает для любого количества файловых дескрипторов, если программа их использует.

Если вы вдруг забудете, можете взглянуть на файл /usr/include/unistd.h:

/* Стандартные файловые дескрипторы.  */
#define STDIN_FILENO    0   /* Стандартный ввод.  */
#define STDOUT_FILENO   1   /* Стандартный вывод.  */
#define STDERR_FILENO   2   /* Стандартный вывод ошибок.  */

На эту тему стоит отметить, что я писал инструменты на C, которые используют нестандартные файловые дескрипторы для пользовательского логирования, так что вы их не увидите, если не переадресуете вывод в файл или что-то подобное.

0

Конструкция 2>&1 перенаправляет стандартный поток ошибок (stderr) в текущее местоположение стандартного вывода (stdout). Этот нюанс, касающийся порядка операций, часто игнорируется в других ответах.

Вы можете перенаправить любой поток вывода на другой с помощью данного метода, но чаще всего он используется для объединения потоков stdout и stderr в один поток для последующей обработки.

Вот несколько примеров:

# Ищем строку ERROR в stdout и stderr.
foo 2>&1 | grep ERROR

# Запускаем просмотрщик less без вмешательства stderr в вывод.
foo 2>&1 | less

# Отправляем stdout и stderr в файл (с добавлением) и терминал.
foo 2>&1 | tee /dev/tty >> outfile

# Направляем stderr в обычное место, а stdout в файл.
foo > outfile1 2>&1 > outfile2

Обратите внимание, что последний пример не перенаправит stderr в outfile2 — он перенаправит его в то место, где находился stdout на момент, когда был встретен аргумент (outfile1), а затем перенаправит stdout в outfile2.

Это позволяет производить довольно изощренные манипуляции с потоками вывода.

0

2 - это стандартный поток ошибок консоли.

1 - это стандартный поток вывода консоли.

Это стандарт для Unix, и Windows также следует спецификации POSIX.

Например, когда вы выполняете команду:

perl test.pl 2>&1

стандартный поток ошибок перенаправляется в стандартный поток вывода, так что вы можете видеть оба вывода вместе:

perl test.pl > debug.log 2>&1

После выполнения вы сможете увидеть весь вывод, включая ошибки, в файле debug.log.

perl test.pl 1>out.log 2>err.log

В этом случае стандартный вывод будет перенаправлен в out.log, а стандартный поток ошибок - в err.log.

Я рекомендую вам попытаться разобраться в этих механизмах.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь