2013-07-16 4 views
1

Это довольно просто войти как стандартный вывод и стандартный поток ошибок из команды в лог-файл:Bash: войти стандартный вывод и стандартный поток ошибок, сохраняя при этом порядок и происхождение

./foo.sh &> log.txt 

Проблема заключается в том, что при проверке файла журнала, один не знает, какая линия из этого потока. Это может быть исправлено путем перенаправления stdout и stderr на два отдельных файла, но тогда хронология и перемежение вывода теряются.

Другим решением будет перенаправление на три файла. Один - с stdout, один с stderr, и один с обоими вместе взятыми. Что-то вроде:

./foo.sh 2> >(tee stderr | tee -a combined) 1> >(tee stdout | tee -a combined) 

Но это не очень элегантно, чтобы иметь так много файлов (и эта команда еще отвалов копию вывода на корпусе).

я нашел интересную функцию Баша, которая будет окрашивать только Stderr сообщения в красном цвете:

color()(set -o pipefail;"[email protected]" 2>&1>&3|sed $'s,.*,\e[31m&\e[m,'>&2)3>&1 

но не сохраняет порядок выхода и результат нечитаемый в текстовом редакторе. Учитывая следующую программу для foo.sh:

for i in 1 2; do 
    for j in 1 2; do 
    printf '%s\n' "out $i" 
    done 
    for k in 1 2; do 
    printf '%s\n' "err $i" >&2 
    done 
done 

Запуск color ./foo.sh производит:

out 1 
out 1 
out 2 
out 2 
[31merr 1[m 
[31merr 1[m 
[31merr 2[m 
[31merr 2[m 

Как можно легко закончить с чем-то таким, как это в одном файле журнала?

@| out 1 
@| out 1 
$| err 1 
$| err 1 
@| out 2 
@| out 2 
$| err 2 
$| err 2 
+0

Рассматривались ли [logging to syslog] (http://linux.die.net/man/1/logger)? –

+0

Не понимаю, как это могло бы помочь отличить stdout и stderr от команды? – xApple

+1

Идея состоит в том, чтобы регистрировать любое сообщение, которое вы хотите регистрировать непосредственно в syslog с соответствующим уровнем журнала, и не беспокоиться о STDOUT и STDERR. Если это не применимо в вашем случае, возможно, что-то вроде этого: 'command 2>> (sed 's/^/ERR: /' >> out.txt) >> out.txt'? –

ответ

2

может быть, вы ищете script он записывает как стандартный вывод, STDERR и команды ... она запускает новую оболочку, в которой он записывает все (или использовать -c _cmd_)

$ script tx1 

ваш color() функция отменяет порядок, потому что sed является буферизацией ...

1

Как насчет перенаправления stderr на ./tmperr и stdout на ./tmpout, теперь запускайте два сценария в фоновом режиме, ntinuously прочитать одну строку из tmperr или tmpout, а затем удалить эту строку? Это, очевидно, меньше идеального, но если есть приличная задержка в реальном скрипте foo.sh, это должно сработать.

Смежные вопросы