Оболочка Linux: передача stderr и stdout в один файл И в отдельные файлы одновременно (используя tee?)
Я хотел бы сформировать поток канала, который захватывает stdout в один файл и stderr в другой файл И оба в третий файл (так что полный вывод терминала находится в одном файле)
Ну вот как то так:
process ----+-- <stdout> --- + --- stdlog.txt
| |
| }---- <terminal> --- alllog.txt
| |
\-- <stderr> --- +---- errlog.txt
Я знаю, что мне нужно использовать футболку, но не могу понять. У вас есть решение? Предпочтителен Баш/ш...
Спасибо за любую помощь, я очень ценю это !!!
1 ответ
Во-первых: я бы не рекомендовал вам этого делать, добавление к зарегистрированным сообщениям меток времени и меток, таких как [ИНФО] и [ОШИБКА] в одном файле или просто меток времени в двух файлах, вероятно, было бы лучшей и более надежной идеей в длительный пробег. при этом позволяя вам создать другой файл, который вы хотите, с помощью grep или сортировки.
К вашей проблеме: мне никогда не приходилось этого делать, но вам, вероятно, придется использовать именованные каналы. Непроверенный пример bash:
# Log one output type
function logger() {
unique_file="$1"
common_file="$2"
# Tee reads from the function's standard input, writes to unique_file, appends to common_file, then outputs what was written
tee "$unique_file" | tee -a "$common_file"
}
# Call your code's main function to start processing
main > >(logger info_log_file common_log_file) 2> >(logger error_log_file common_log_file >&2)
У вас может возникнуть соблазн использоватьexec >"$info_pipe" 2>"$error_pipe"
. Не делайте этого, иначе вы создадите цикл, который заставит ваш файл журнала заполнить все доступное дисковое пространство.
Обратите внимание: если ваш bash не поддерживает неявные именованные каналы (должен быть, но я видел среды, в которых это не поддерживается), вы можете захотеть использовать их явно, вызвав mkfifo, однако для этого потребуется больше возможностей:
# Log one output type
function logger() {
unique_file="$1"
common_file="$2"
# Tee reads from the function's standard input, writes to unique_file, appends to common_file, then outputs what was written
tee "$unique_file" | tee -a "$common_file"
}
# Setup logging
function prepare() {
tmp_pipe_dir="$(mktemp -d)"
error_pipe="$(mkfifo "$tmp_pipe_dir/error")"
info_pipe="$(mkfifo "$tmp_pipe_dir/info")"
}
function cleanup() {
rm -rf "$tmp_pipe_dir"
}
prepare
# Start logging, note that logger won't stop on its own. Removing the pipe files should do the trick
logger info_log_file common_log_file <"$info_pipe" &
logger error_log_file common_log_file <"$error_pipe" >&2 &
# Call your code's main function to start processing
main >"$info_pipe" 2>"$error_pipe"
cleanup