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

stdout = 1 (общий поток вывода)
stderr = 2 (поток с ошибками)

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

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

Вот для этого и требуется указать символ & (амперсанд) перед 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.

В официальной документации () этот момент хорошо расписан, но я расписал еще проще.
04.11.2023 15:53
OlegON
 
Обращу еще внимание, что если перенаправления два, то их порядок имеет значение.
То есть (проверьте)
Код:
&>file 2>&1
и
Код:
2>&1 &>file
дадут разный результат, если не ошибаюсь, надо писать, как в первом варианте, каждый раз забываю.
Часовой пояс GMT +3, время: 16:43.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.