Объясните команду bash " exec>>(tee $LOG FILE) 2>&1"


Мое намерение состояло в том, чтобы все выходные данные моего сценария bash отображались на консоли и записывались в файл.

Вот мой сценарий, который работает, как и ожидалось.

#!/bin/bash

LOG_FILE="test_log.log"
touch $LOG_FILE

# output to console and to logfile
exec > >(tee $LOG_FILE) 2>&1

echo "Starting command ls"
ls -al
echo "End of script"

Однако я не понимаю, почему это работает именно так.

Я ожидал, что будет exec >>(tee $LOG_FILE) 2>&1 работа, но она не работает, хотя exec >>$LOG_FILE 2>&1 действительно работает.

Я не смог найти причину для построения exec > >(command ) в руководстве bash, ни в advanced bash scripting. Можете ли вы объяснить логику этого ?

1 2

1 ответ:

>(tee $LOG_FILE) является примером подстановки процесса, вы можете захотеть поискать это. дополнительно раковина Scriptng и Баш инструкцию

Используя синтаксис <(program) для захвата выходных данных и >(program) для подачи входных данных, мы можем передавать данные только по одной записи за раз. Он более мощный, чем подстановка команд (backticks или $( )), потому что он заменяет имя файла , а не текст. Поэтому везде, где файл обычно указан, мы можем заменить a стандартный вывод или ввод программы (хотя подстановка процесса на входе не так уж часто встречается). Это особенно полезно, когда программа не использует стандартные потоки для того, что вы хотите.

Обратите внимание, что в вашем примере вы пропускаете пробел, exec >>(tee $LOG_FILE) 2>&1 является неправильным (вы получите синтаксическую ошибку),

exec > >(tee $LOG_FILE) 2>&1
Правильно, что пространство критично.

Таким образом, Часть exec > изменяет файловый дескриптор 1 (по умолчанию), также известный как stdout или стандартный вывод , чтобы ссылаться на "все, что будет дальше", в данном случае это подстановка процесса, хотя обычно это было бы имя файла.

2>&1 перенаправить файловый дескриптор 2, stderr илиСтандартная ошибка для ссылки на то же место, что и файловый дескриптор 1 (Если вы опустите &, вы получите файл с именем 1).

После того, как вы это сделали, вы изменили стандартный вывод текущего процесса, поэтому выходные данные из команд, которые следуют, переходят к этому процессу tee.