Можно ли печатать только stdout на экран при записи stdout и stderr в файл журнала? - PullRequest
1 голос
/ 11 апреля 2020

Я знаю, что можно перенаправить оба файла в указанный c файл:

./command 1> out.log 2> err.log

или

./command 1>test.log 2>&1

, чтобы записать оба файла. Но я не знаю, как записать оба файла в один и тот же файл (сохраняя порядок вывода) при печати только одного из них. tee не очень полезно, потому что печатает оба дескриптора файла.

Ответы [ 5 ]

2 голосов
/ 11 апреля 2020

Запись стандартного вывода в один файл и оба в другой довольно проста с помощью tee:

{ cmd | tee stdout.log; } &> both.log

Оба дескриптора составной команды перенаправляются на both.log, но стандартный вывод cmd сначала передается через tee в stdout.log, а затем записывается в both.log.

Запись стандартной ошибки в одну и обе в другую более сложна.

{ foo 2>&1 1>&3 | tee stderr.log ; } 3>&1 | tee both.log > /dev/null

Это немного сложно описать правильно. Во-первых, стандартная ошибка группы команд игнорируется; это стандартный вывод по трубе на tee both.log. Но 3>&1 также копирует свой fd 3 в стандартный вывод. Итак, вопрос в том, что записывается в это?

Внутри группы команд стандартный вывод foo - это канал к tee stderr.log. 2>&1 копирует tee's стандартную ошибку в этот дескриптор, а 1>&3 копирует foo's стандартный вывод в унаследованный fd 3.

1 голос
/ 11 апреля 2020

Чтобы ответить на вопрос:

stderr на консоль и stdout и ошибка в файл?

{ cmd 3>&1 1>&2 2>&3 | tee /dev/tty; } &> /tmp/both.log

3>&1 1>&2 2>&3 означает обмен stdout и stderr

1 голос
/ 11 апреля 2020

стандартный вывод на консоль и стандартный вывод и ошибка в файл?

{ cmd | tee /dev/tty; } &> /tmp/both.log
1 голос
/ 11 апреля 2020

Вы можете использовать несколько перенаправлений:

foo () { echo 1 ; echo 2 >&2 ; }
(( foo | tee >(cat) >&3) &>log ) 3>&1

Команда tee отправляет stdout файловым дескрипторам 1 (через подстановка процесса ) и 3. И stdout, и stderr перенаправляются на журнал. В конце 3, копия stdout отправляется обратно на терминал.

В качестве альтернативы, вы можете обойтись без подстановки процесса, перенаправить вывод напрямую в журнал, но использовать -a и >> для добавления. Вам необходимо очистить журнал заранее.

: > log; (( foo | tee -a log >&3) 2>> log ) 3>&1
1 голос
/ 11 апреля 2020

Будет лучше записать их в разные файлы, в этом случае это будет очень просто:

cmd 2>/stderr.log| tee -a stdout.log

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

...