Захват STDERR и STDOUT в файл с помощью тройника

16

Мне неясно, какой лучший порядок для записи обоих STDERRи STDOUTодного файла с использованием tee. Я знаю, что если я хочу передать в файл, я должен сопоставить дескриптор файла после перенаправления, т.е.

find . >/tmp/output.txt 2>&1

Это указывает на оболочку , чтобы отправить STDOUTна , /tmp/output.txtа затем отправить STDERRна STDOUT(теперь отправка /tmp/output.txt).

Попытка выполнить 2>&1перед перенаправлением файла не даст желаемого эффекта.

Однако, когда я хочу использовать конвейер, teeэто должно быть:

find . |tee /tmp/output.txt 2>&1   # or
find . 2>&1 |tee /tmp/output.txt   # ?
PP.
источник

Ответы:

19

Последний; он гарантирует, что STDOUT и STDERR исходной команды перейдут к одному и тому же fd, а затем подадут их вместе в тройник. В первом случае это STDERR команды tee, к которой вы присоединитесь с ее STDOUT.

Безумный Шляпник
источник
5
Интересно, что страница руководства bash говорит: «Если |&используется, стандартная ошибка command1 связана со стандартным вводом command2 через канал; это сокращение для 2>&1 |. Это неявное перенаправление стандартной ошибки выполняется после любых перенаправлений, указанных командой».
пп.
Мне пришлось создать небольшую программу на C, которая пишет и для, stderrи stdoutдля понимания этой проблемы. Операторы перенаправления >и tee |отличаются при попытке захвата обоих выходных потоков. Для перенаправления мне пришлось ./testapp > /tmp/out.log 2>&1. Тогда как для тройника мне пришлось ./testapp 2>&1 | tee /tmp/out.log.
typelogic
@daixtr за то, что он стоит, |обычно упоминается как оператор канала. teeотносится только к конкретной программе, которая вызывается на дальнем конце канала.
MadHatter