检索运行时标准输出并存储在变量中

时间:2015-03-24 20:38:46

标签: bash shell

基本上我想把一些错误交给我的bash脚本(task.sh):

#!/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

我尝试运行bash test.sh | tee -a /var/log/test.log但是,它不起作用,因为当脚本仍在运行时,“tee”甚至不会开始工作,但是,我确实希望给管理员一个有用的信息,即完整标准,如何实现这一目标呢?

1 个答案:

答案 0 :(得分: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退出:

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

由于问题包括&#34;并存储在变量&#34; - 忽略示例中给出的邮件用法,可以简单如下:

stdout=$(<"$stdout_log")

也就是说,如果您想通过电子邮件发送日志,即使您想添加页眉和页脚,也不一定需要将其加载到变量中;一个heredoc可以为你做到这一点:

mailx admin@example.com -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