Сейчас за кружкой чая кореш задал вопрос: «Ромыч, а расскажи мне, что означает 2>&1?» Хм… Нашёл время, а так хорошо сидели.

Расскажу и тебе, понятное дело, что это магия со стандартными потоками вывода.

Как мы знаем, потоки вывода имеют файловые дескрипторы:

  • stdout = 1 — общий поток вывода;
  • stderr = 2 — поток с ошибками.

Получается (2>&1) = stderr > stdout. То есть направляем поток с ошибками в стандартный поток вывода. Ошибки будут выводиться на экран в терминале.

Логичным было бы сделать конструкцию 2>1. Но, увы, эта схема отработает другую логическую операцию. Поток с ошибками stderr будет писать все данные в файл, у которого название будет 1.

Роман Шубин
Роман Шубин
CEO & CTO, Главред в «Цифровой улей»
Задать вопрос
Вот для этого и требуется указать символ & (амперсанд) перед stdout. Это будет интерпретировано как файловый дескриптор, а не обычный файл.

А почему тогда не &2>&1? Логично же? Но нет! Символ & интерпретируется как файловый дескриптор только в контексте перенаправления.

Операция command &2>&1 анализируется так: command & 2>&1. То есть команда command будет выполняться в фоновом режиме. А затем начнёт выполняться команда 2 с перенаправлением на стандартный вывод stdout.

Вот такие дела. А ещё есть альтернатива с оператором |&.

|& — это сокращённый вариант от 2>&1 |.

Пример:

script.sh |& tee -a /var/log/script.log

Всё, что script.sh выведет в потоки stdout и stderr, будет перенаправлено в файл script.log.

В официальной документации этот момент хорошо расписан, но я расписал тебе ещё проще.

Как говорится — мы из рощи, мы попроще! Всё, не смею тебя больше отвлекать, спасибо за внимание. Увидимся, скорее всего, в понедельник или вторник. Если чо, пиши в чатик, мы там завсегда тебе рады!