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

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

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

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

3 ответа3

2

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

./myprog  > >(logger -t myprog-out)  2> >(tee /dev/tty | logger -t myprog-err)
1

См. 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

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

0

Я работал над ответом ниже, но столкнулся с проблемой, которая может иметь отношение к другим ответам, а также к проблемам, которые не используют 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 , чтобы она была видна на консоли, а затем на регистраторе.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .