2015-03-24 3 views
1

В основном я хочу сделать некоторые вручая ошибки в моем Баше скрипте (task.sh):Получить выполнение STDOUT и хранить в переменной

#!/bin/bash 
# step 1 
# step 2 
# step 3 
# step n 
if [ -f "/tmp/foo.bar" ]; then 
    # full_shell_output=? 
    # Send email to admin with all the stdout before this 
fi 

Я попытался запустить Баш test.sh | tee -a /var/log/test.log, однако, он не работает, так как когда скрипт все еще работает, «tee» даже не начнет работать, однако я хочу дать администратору полезную информацию, то есть полный stdout, как этого добиться, пожалуйста?

+0

В чем проблема? Что вы не видите вывод на консоли сразу? –

+0

@ EtanReisner, я предполагаю, что проблема в том, что тэ не удалил все на диск, когда содержимое на диске отправляется по почте ... но, действительно, поскольку OP не описывает проблему подробно, она приходит вплоть до угадывания. –

+0

Извините за запутанность, @CharlesDuffy был прав, проблема для меня: когда произошла какая-то ошибка, я хочу сбросить все содержимое stdout в сообщения электронной почты администраторам, однако в этот момент процесс «tee» пока еще начиная с момента запуска скрипта. –

ответ

2
stdout_log=$(mktemp -t stdout.log.XXXXXX) 
exec >"$stdout_log" # redirect all stdout to file 

# ...do things that need to be logged here... 

if need_to_mail_the_log; then 
    exec >/dev/null # closes, and thus flushes, the original log 
    mail admin <"$stdout_log" 
fi 

Теперь, если вы хотите, чтобы он tee'd на консоль, которая получает небольшое немного сложнее, так как вам нужно ждать, чтобы выйти из tee:

stdout_log=$(mktemp -t stdout.log.XXXXXX) 
exec 3>"$stdout_log" 
exec > >(flock -x 3; tee "$stdout_log")) # send stdout to tee to the file 

# ...do things that need to be logged here... 

if need_to_mail_the_log; then 
    exec >/dev/null # close the handle writing to tee 
    flock -x 3  # grab a lock on the log; this will only succeed after tee exits 
    mail admin <"$stdout_log" 
fi 

С вопрос включает в себя «и хранить в переменной» - игнорируя использование почтовой рассылки, приведенное в вашем примере, которое может быть простым:

Если вы хотите отправить журнал по электронной почте, вам необязательно загружать его в переменную вообще, даже если вы хотите добавить верхние и нижние колонтитулы; a heredoc может это сделать для вас:

mailx [email protected] -s "log from some process" <<EOF 
Hey! I ran that thing you asked for, and got this message: 

$(<"$stdout_log") 

Please look into it; thanks! 
EOF 
+0

BTW, у меня в оригинале был мозг (закрытие FD 3, прежде чем пытаться использовать его для блокировки); это исправлено сейчас. –

+0

Спасибо, Чарльз, для меня есть одно непонятное: mail admin <"$ stdout_log", можете ли вы обновить эту строку до эха или кошки, чтобы я мог получить более четкое понимание; или вы можете вставлять контент в «stdout» в строковую переменную, так как в конечном итоге это станет частью тела электронной почты, спасибо большое! –

+0

@WayneYe, '$ stdout_log' расширяет имя файла, который содержит перенаправленный контент. Таким образом, чтение из файла имеет важное значение. Тем не менее, этот конкретный подход - это то, что вы будете использовать, если журнал является * целым * телом электронной почты. Если вам нужен другой контент, кроме журнала, то да, будут какие-то изменения ... но можете ли вы подтвердить, что об этом вы спрашиваете? Я не совсем понимаю, что вы подразумеваете под своим комментарием. –

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