Я видел это в верхней части моего файла сценария bash:
export LOGFILE=$LOGDIRECTORY/${SCRIPT_NAME}.log
exec > >(tee $LOGFILE)
exec 2>&1
Что оно делает? Что здесь делают два exec-процесса? Я понимаю, что, сохраняя это таким образом, все результаты выполнения скрипта передаются по конвейеру, $LOGFILE
но я хотел понять это с точки зрения exec
утверждений.
exec
строки вполне могут быть просто одна (exec > >(tee "$LOGFILE") 2>&1
).Ответы:
В оболочках:
exec
1) открытия и перенаправления файлов; 2) актуальноеexec
(замена текущего образа процесса другим образом процесса).Это
exec
перенаправления.Сначала вы перенаправляете (
exec 1> >(tee $LOGFILE)
)stdout
дескриптор (1) к каналу, генерируемому подстановкой процесса, подключенному к параллельно выполняемомуtee
процессу, который имеет в$LOGFILE
качестве первого аргумента, а затем вы перенаправляетеstderr
дескриптор (2) в то же место, куда1
сейчас указывает дескриптор (тройник труба).Помня о том, что файловые дескрипторы наследуются, вы только что сделали все будущее
stdout
иstderr
выходные данные отправлены вtee
процесс, который записывает его$LOGFILE
и туда, куда изначально указывал файловый дескриптор 1 (возможно, ваш терминал).Примечание: процесс тройника выводится в исходный стандартный вывод (= исходный дескриптор файла 1), потому что, как вы можете узнать из / search bash (1) для простого расширения команды и замены процесса, подстановка процесса (
>()
<()
) происходит (вместе с другими расширениями) перед перенаправления выполняются, что означает, что перенаправлениеexec 1> >(tee "$LOGFILE")
происходит послеtee
запуска, оставляяtee
с тем же файловым дескриптором 1, который он унаследовал от родительской оболочки. (Если бы это было наоборот,tee
было бы сделано для записи в его собственный ввод, который мог бы сделать это тупиком, в зависимости от его шаблона ввода-вывода).источник