在 shell 脚本里打日志
今天小弟在重构代码中的一个脚本模块,其中涉及到日志功能。上午花了点儿时间想出了个在 shell 打日志的技巧,觉得值得写一下。
希望要实现的效果是:实现一个 write_log 命令,给一条出错消息作为输入,write_log 记录日志时自动加上 时间戳、脚本文件名和行号。形如:
2010-12-17 19:13:44 [work.sh:24] FATAL: mkdir -p /x.
时间戳、脚本文件名都好获得,但是行号就没那么容易实现了。shell 中的 $LINENO 变量只能展开成当前行的行号,如果把 write_log 实现成函数的话,势必在函数中无法使用 $LINENO。
开始我想了好大一会儿,觉得 eval 能干这个事情。但是如果用 eval 的话,还不如直接把 $LINENO 传给 write_log 函数呢,与我的初衷不是太相符。我拉来同事讨论了一把,也没解决问题。正当我准备放弃了,计划每次传 $LINENO 参数时,忽然想起来,怎么把 alias 给忘了呢?
于是,write_log 的实现就是这个样子了:
function _write_log()
{
if [ $# -eq 2 ]; then
if [ -z $LOGFILE ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") [$0:$1] $2"
else
echo "$(date "+%Y-%m-%d %H:%M:%S") [$0:$1] $2" >> $LOGFILE
fi
elif [ $# -eq 1 ]; then
if [ -z $LOGFILE ]; then
echo "$(date "+%Y-%m-%d %H:%M:%S") [$0] $1"
else
echo "$(date "+%Y-%m-%d %H:%M:%S") [$0] $1" >> $LOGFILE
fi
else
return 1
fi
}
alias write_log='_write_log $LINENO' # 这里必须使用单引号
存在的问题是:上面这段代码在 bash 里是不工作的,但是用 sh 可以――即使 sh 也是链接到 bash 的。问题出在 alias 上,可以把问题简化成这样,有一个脚本 a.sh:
$ cat a.sh alias lss='ls -l' lss /tmp
这个脚本用 /bin/sh 执行是这样的:
$ sh a.sh total 8 drwx------ 2 gdm gdm 4096 2010-12-17 19:34 orbit-gdm drwx------ 2 gdm gdm 4096 2010-12-17 11:04 pulse-PKdhtXMmr18n
用 /bin/bash 执行是这样的:
$ bash a.sh a.sh: line 2: lss: command not found
把 bash 随便 link 成一个叫 sh 的链接文件,再执行是类似这样的:
$ ln -s /bin/bash ~/sh $ ~/sh a.sh total 8 drwx------ 2 gdm gdm 4096 2010-12-17 19:34 orbit-gdm drwx------ 2 gdm gdm 4096 2010-12-17 11:04 pulse-PKdhtXMmr18n
这个问题肯定是有原因的,我不愿意去翻 bash 源代码,也不知道哪里去找答案,所以我放弃了,直接在文件头加上
#!/bin/sh
如果哪位兄台知道这种“奇怪”现象的原因所在,请不吝赐教
建议继续学习:
- server日志的路径分析 (阅读:10119)
- AWStats简介:Apache/Windows IIS的日志分析工具的下载,安装,配置样例和使用(含6.9中文定义补丁) (阅读:8865)
- 利用脚本分析日志并利用snmp自定义OID,再通过cacti画图 (阅读:8691)
- tomcat catalina.out日志切割每天生成一个文件 (阅读:8092)
- 分布式日志系统scribe使用手记 (阅读:8048)
- 你可能不知道的Shell (阅读:6938)
- AWStats是一个基于Perl的WEB日志分析工具。 (阅读:6113)
- 面向对象的Shell脚本 (阅读:5160)
- 使用nginx记日志 (阅读:5085)
- 大于2GB的Listener.log和运行超过198天的主机上的Oracle实例 (阅读:4880)
扫一扫订阅我的微信号:IT技术博客大学习
- 作者:Solrex Yang 来源: Solrex Shuffling
- 标签: shell 日志
- 发布时间:2010-12-21 23:14:12
- [43] IOS安全–浅谈关于IOS加固的几种方法
- [43] 如何拿下简短的域名
- [42] Oracle MTS模式下 进程地址与会话信
- [42] 图书馆的世界纪录
- [41] 界面设计速成
- [39] 【社会化设计】自我(self)部分――欢迎区
- [39] android 开发入门
- [37] 读书笔记-壹百度:百度十年千倍的29条法则
- [36] 视觉调整-设计师 vs. 逻辑
- [33] Go Reflect 性能