Добавить текст в перенаправление stderr в bash
Сейчас я использую exec для перенаправления stderr в журнал ошибок с
exec 2>> ${errorLog}
Единственным недостатком является то, что я должен запустить каждый запуск с отметкой времени, поскольку exec просто подталкивает текст прямо в файл журнала. Есть ли способ перенаправить stderr, но разрешить мне добавлять к нему текст, например метку времени?
Ответы
Ответ 1
Это очень интересно. Я спросил парня, который знает bash неплохо, и он сказал мне так:
foo() { while IFS='' read -r line; do echo "$(date) $line" >> file.txt; done; };
Во-первых, это создает функцию, считывающую одну строку исходного ввода из stdin, в то время как присвоение IFS делает это, не игнорирует пробелы. Прочитав одну строку, он выводит ее с соответствующими данными. Затем вы должны указать bash перенаправить stderr в эту функцию:
exec 2> >(foo)
Все, что вы пишете в stderr, теперь будет проходить через функцию foo. Обратите внимание, что когда вы делаете это в интерактивной оболочке, вы больше не увидите приглашение, потому что оно напечатано в stderr, а чтение в foo - буферизировано в строке:)
Ответ 2
Вы можете просто использовать:
exec 1> >( sed "s/^/$(date '+[%F %T]'): /" | tee -a ${LOGFILE}) 2>&1
Это не будет полностью решить вашу проблему, касающуюся Prompt, не отображаемой (itt будет отображаться через короткое время, но не в режиме реального времени, так как канал будет кэшировать некоторые данные...), но будет отображать вывод 1:1 на stdout как а также в файле.
Единственная проблема заключается в том, что я не мог решить, делать это из функции, поскольку это открывает подоболочку, где exec бесполезен для основной программы...
Ответ 3
В этом примере перенаправляются stdout и stderr без потери исходного stdout и stderr. Также ошибки в обработчике stdout записываются в обработчик stderr. Дескрипторы файлов сохраняются в переменных и закрываются в дочерних процессах. Bash заботится о том, чтобы не возникало столкновений.
#! /bin/bash
stamp ()
{
local LINE
while IFS='' read -r LINE; do
echo "$(date '+%Y-%m-%d %H:%M:%S,%N %z') $$ $LINE"
done
}
exec {STDOUT}>&1
exec {STDERR}>&2
exec 2> >(exec {STDOUT}>&-; exec {STDERR}>&-; exec &>> stderr.log; stamp)
exec > >(exec {STDOUT}>&-; exec {STDERR}>&-; exec >> stdout.log; stamp)
for n in $(seq 3); do
echo loop $n >&$STDOUT
echo o$n
echo e$n >&2
done
Для этого требуется текущая версия Bash, но благодаря Shellshock можно полагаться на это в настоящее время.
Ответ 4
Я просто искал ту же самую аккуратную вещь. Увидев этот пост, я увидел еще один подход, который выглядит многообещающим: http://utcc.utoronto.ca/~cks/space/blog/unix/PipingJustStderr
Ответ 5
cat q23123 2> tmp_file ;cat tmp_file | sed -e "s/^/$(date '+[%F %T]'): /g" >> output.log; rm -f tmp_file