Отправить stderr другому получателю в конвейере

pts / 0 сообщает вам, к какому «псевдотерминалу» вошел пользователь. В данном случае это терминал 0,1,2 и т. Д.
Терминал - это собственное терминальное устройство, а серверная часть - аппаратная или эмулированная ядро.
Pts (псевдотерминальное устройство) - это терминальное устройство, которое эмулируется другой программой (например, такими программами являются xterm, screen или ssh).

1
07.05.2018, 10:50
1 ответ

Во-первых, давайте создадим программу run_test, которая генерирует и stdout, и stderr:

$ run_test() { while sleep 0.2; do echo "Out $((++c))"; echo "err$c">&2; done; }

Теперь давайте отправим stdout и stderr на разные фильтры. Поскольку у меня не установлен prepend, я буду использовать sedдля той же цели :

.
$ exec 3>&2; { run_test | sed 's/^/stdout: /'; } 2>&1 1>&3 | sed 's/^/stderr: /'
stdout: Out 1
stderr: err1
stdout: Out 2
stderr: err2
stdout: Out 3
stderr: err3

Как это работает

  • exec 3>&2

    Это создает файловый дескриптор 3 как дубликат stderr.

  • run_test | sed 's/^/stdout: /'

    Это запускает run_testи добавляет stdout:к началу стандартного вывода.

  • { run_test | sed 's/^/stdout: /'; } 2>&1 1>&3

    2>&перенаправляет stderr на stdout, чтобы stderr перешел в следующий канал. 1>&3перенаправляет стандартный вывод на стандартный вывод, чтобы он отображался на терминале.

  • { run_test | sed 's/^/stdout: /'; } 2>&1 1>&3 | sed 's/^/stderr: /'

    Последний канал захватывает stderr теста run _, (, который теперь является stdout ), и добавляет к нему stderr:.

Использование замены процесса

$ run_test > >(sed 's/^/stdout: /') 2> >(stdbuf -oL sed 's/^/stderr: /' >&2)
stdout: Out 1
stderr: err1
stdout: Out 2
stderr: err2
stdout: Out 3
stderr: err3

В приведенном выше примере используется stdbuf, который является стандартным для Linux. Для других ОС нужно будет поискать аналогичные команды.

3
27.01.2020, 23:32

Теги

Похожие вопросы