天天看点

linux shell编程学习--日志工具

在使用高级语言如java,C++的时候,有专门的日志库,比如log4j,log4cxx等一些专门的日志库,进行日志打印,可以进行日志等级配置,日志的文件名,行号等信息的自动添加。但是在shell里,好像没有类似的日志库(也许是有,但我不知道,如果有知道的,请指点一下)。大部分时候,我们都是使用echo进行输出。本文的介绍了一种可以不依赖任何第三方库的前提下,shell日志自动添加日志打印的文件,行号,日期等信息的简便方法,方便shell脚本可以使用简单的echo命令进行日志输出调试。

下面就一步步介绍,我的日志工具的进化史。

一、树上的猴子

这个时候,作为一个猴子,除了摘树上的香蕉,那就是摘树上的苹果啦。这个时候,只能使用最简单的echo进行日志打印,并且使用重定向,进行标准输出stdout和标准错误输出strerr。对日志进行两种形式的输出。

echo "Print log to stdout."
echo "Print log to stderr." >&
           

二、山顶洞人

作为人猿,除了吃。最简单的御寒,也是需要的啦。日志虽然已经分类了,但我们肯定希望在日志里,看到一些更详细的基本信息,如打印日志发生日期,日志发生的脚本名称,日志输出所在的行号等信息,可以方便调试。

日期信息,可以使用shell的date命令,可以自动打印出当前日期

日志文件,shell脚本的$0就是日志文件

日志行号,像C/C++一样,shell有个内置的变量叫LINENO,可以取到echo所在行号.

echo "[`date` $0 $LINENO] Print  log to stdout."
echo "[`date` $0 $LINENO] Print  log to stderr." >&
           

三、春秋奴隶社会

人类进化到了文明,那就有了分工。一部分人干体力,如奴隶,一部分干脑力,如贵族。日志也是一样道理的。像日期,行号等这种基本信息,就没有必要在每个打印日志的地方都加上,那样太麻烦了。在一个地方,统一处理下,就可以了,好比log4j那样。调用处,只需要给出日志内容就ok了。这个时候,就想到高级语言里的函数了,shell里,也是可以定义函数的。那就定义个函数

log_out(){
     echo "[`date` $0 $1] $2"
}
log_err(){
     echo "[`date` $0 $1] $2" >&
}
           

定义好函数,就可以在每个需要输出日志的地方进行打印了。

log_out(){
     echo "[`date` $0 $1] $2"
}
log_err(){
     echo "[`date` $0 $1] $2" >&
}

log_out  "$LINENO" "Print log to stdout"
log_err "$LINENO" "Print log to stderr"
           

上面函数虽然可以解决问题,但这种函数有2个问题,1.行号需要在调用处传入,2.函数需要写在每个文件里定义。

关于问题1,可以使用shell提供的关键字alisa,alisa可以提供别名。

关于问题2,可以把函数定义在一个公共文件里,在每个使用的文件里source文件。

定义一个文件com_util.sh如下:

log_out_impl(){
     echo "[`date` $0 $1] $2"
}
log_err_impl(){
     echo "[`date` $0 $1] $2" >&
}
shopt -s expand_aliases
alias log_out='log_out_impl $LINENO'
alias log_err='log_err_impl $LINENO'
           

在使用的地方,进行文件引入,就可以了

[email protected]:tmp$ cat ./test_log.sh 
#!/bin/bash
source com_util.sh

log_out "Print log to stdout"
log_err "Print log to stderr"

[email protected]:tmp$ ./test_log.sh 
[年 月 日 星期六 :: CST ./test_log.sh ] Print log to stdout
[年 月 日 星期六 :: CST ./test_log.sh ] Print log to stderr