Как записать stdout и stderr с разными тегами в системный журнал?

505
Sparkler

Я могу перенаправить как stdoutи stderrна logger этом пути :

./myprog 2>&1 | tee /dev/tty | logger 

но я хотел бы иметь возможность пометить каждую запись журнала " myprog-out" и " myprog-err" в зависимости от того, откуда она взялась ( stdoutи stderrсоответственно).

Я также хотел бы видеть вывод stdout и stderr на экране.

0

3 ответа на вопрос

2
grawity

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

./myprog > >(logger -t myprog-out) 2> >(tee /dev/tty | logger -t myprog-err) 
это очень близко к тому, что мне нужно, но, как есть, я вижу только stderr на экране, но не stdout (они оба регистрируются в syslog по мере необходимости) Sparkler 5 лет назад 0
1
Lewis M

См. Https://stackoverflow.com/questions/9112979/pipe-stdout-and-stderr-to-two-different-processes-in-shell-script

Вы можете заменить sed командами logger -t tag, чтобы они входили в системные журналы.

Вот что я сделал с примером скрипта в приведенном выше URL:

#!/bin/bash  foo() { echo a echo b >&2 echo c echo d >&2 }  { foo 2>&1 1>&3 3>&- | logger -t 'my-err'; } 3>&1 1>&2 | logger -t 'my-stdout'  exit 0 

Надеюсь это поможет

похоже, это тоже работает: `{./foo 2> & 3 | logger -t my-out; } 3> & 1 1> & 2 | logger -t my-err`. Какова функция `2> & 1 1> & 3 3> & -` в вашем ответе? Sparkler 5 лет назад 0
Я следил за тем, что было в URL. В нем говорилось, что вам нужно временно перенаправить стандартный вывод в другой файловый дескриптор, чтобы избежать смешивания стандартных выводов и стандартного вывода. Lewis M 5 лет назад 0
Любая идея, как также по-прежнему поддерживать оба на экране во время их регистрации? Sparkler 5 лет назад 0
Вы можете сделать «tee / dev / tty | logger» вместо просто logger. Это может сработать. Lewis M 5 лет назад 0
0
AFH

Я работал над ответом ниже, но столкнулся с проблемой, которая может иметь отношение к другим ответам, а также к проблемам, которые не используются logger, с его опцией тега, поэтому я отправлю свои выводы.

Во-первых, я сгенерировал смешанные стандартные сообщения об ошибках и выводе сообщений с некоторыми пробелами между ними

echo abc; sleep 1; echo def >&2; sleep 1; echo ghi; sleep 1; echo jkl >&2 

Затем я добавил out:в начало стандартных выходных сообщений:

{ echo abc; sleep 1; echo def >&2; sleep 1; echo ghi; sleep 1; echo jkl >&2; } | \ sed 's/^/out: /g'; 

Затем я добавил err:в поток ошибок, добавив во все записи, а затем удалив out:уже добавленные строки (обратите внимание, что любая используемая строка не out:должна запускать неизмененную запись ошибки):

{ { echo abc; sleep 1; echo def >&2; sleep 1; echo ghi; sleep 1; echo jkl >&2; } | \ sed 's/^/out: /g'; } 2>&1 | sed -e 's/^/err: /g' -e 's/^err: out: /out: /g' 

Ответ Льюиса М. предполагает, что можно было бы использовать перенаправление в поток 3, чтобы избежать двойной замены, но это прекрасно работает с приведенным выше ограничением; однако буферизация означает, что записи не обязательно записываются в том порядке, в котором они были созданы, поэтому я закончил с:

stdbuf -i0 -o0 -e0 bash -c \ "{ { echo abc; sleep 1; echo def >&2; sleep 1; echo ghi; sleep 1; echo jkl >&2; } | \ sed 's/^/out: /g'; } 2>&1 | sed -e 's/^/err: /g' -e 's/^err: out: /out: /g'" | \ tee /dev/tty | logger 

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

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