脚本范围的重定向到内部记录器功能

时间:2013-10-02 23:34:42

标签: bash function redirect logging exec

我写了一个很大的Bash程序,它由在深度目录树中组织的几个shell脚本组成。该程序很复杂,具有熟练的调试和日志记录基础结构是至关重要的。 在其中一个子脚本中,我编写了一个记录器函数,它能够接收日志消息并将它们路由到适当的MySQL表。

记录器函数有一个简单的简单输入接口,它只接受一个参数,即日志消息,可以想象为echo内置函数的特殊版本,它直接打印到数据库中,并确定路由内部。 在代码中,这转换为:

# generic code, somewhere in the program
if success; then
     log_f "Previous function returned success"
else log_f "Previous function returned failure"
fi

这种方法的缺点是只能记录那些明确意味着通过log_f的消息;也就是说,外部二进制文件或Bash本身生成的任何错误消息都不会保存在数据库中。

一个简单的解决方案可以沿着exec >log 2>&1行,它将从stdin和stderr输出的所有内容都注册到log。但是,我需要将日志消息存储在数据库中而不是存档。

此外,exec似乎与管道重定向不兼容,例如exec | log_f。 (log_f已修改为支持stdin)。 我能想到的唯一解决方案是丑陋,它是在调用期间设置整个脚本的重定向,例如:

# I am a starter of sub-scripts
a_script_in_the_tree.sh 2>&1 | log_f

但是,最好让每个脚本在内部管理自己的日志记录方法,使用其范围内可用的自己的一组函数。

2 个答案:

答案 0 :(得分:1)

  

一个简单的解决方案可以沿exec >log 2>&1

行走

命名管道可以取代日志文件,尽管这需要一个fifo-to-sql进程来使用输出并将其发送到数据库。这将使您“自我依赖”每个脚本重定向,同时增加每个脚本启动幂等消费者所需的负担。这对另一个人来说是一种丑陋吗?

这是一对简单的脚本,用于演示这个想法,即需要记录服务的脚本:

$ cat nplog.sh
#!/bin/bash

logfifo=/tmp/log.fifo
if [ ! -p $logfifo ]; then
    # should maybe spawn npreader here
    echo logging system is not running: $logfifo does not exist 1>&2
    exit 1
fi

exec > $logfifo 2>&1 

while true; do
    date
    cat /does.not.exist
    sleep 1
done

和cheezy读者

$ cat npreader.sh
#!/bin/bash

# oversimplified for illustration. should remove the fifo upon exit so
# that clients can't attach when reader is down

logfifo=/tmp/log.fifo
mkfifo $logfifo
cat $logfifo

答案 1 :(得分:0)

刚从脑子里出来:

exec > >(log_f) 2>&1