我们知道在Linux Shell编程中,如果您的处理过程是基于行的文本处理模式,则可以用到很大一批军火库,用管道符号,将相关的处理命令连接起来,进而完成一个比较宏大的功能。
在组合使用shell命令的选择中,使用后台job,或也可以成为另外一种选择,但一般意味着命令协作协议更外私有,和耦合更紧!
笔者就遇到一个非常古怪的日志系统,但碍于使用这个日志模块年代比较久远,大家已经习惯,所以,一直没有人想着换掉它。
这个老旧的日志系统,支持多线程输入,而且可以根据设定磁盘用量大小进行切分文件,但切分文件,是文件名字加编号,特别地,编号顺次在一个数值范围内回环增长。
如果你使用`tail -F /path/to/logfile`,那么在日志文件切换时,也不能自动切换到下一个,因为下一个输出文件名字已经不同!
对比现在比较经典的日志系统,在实现我说的那个旧日志模块所有的能力外,均能保持当前日志输出文件名字不发生变化,对使用`tail -F /path/to/logfile`跟踪日志输出极其友好。
但,既然已经如此这样了,那么有没有办法实现持续不断地跟踪日志输出呢?
最后,想到的一个办法就是使用job和sleep睡眠醒后观察,且利用job和启用观察日志命令共享使用标准输出的方式,实现对旧日志系统输出文件的持续观察 :)
代码如下:
#!/bin/sh
if [ ! -r "$1" -o ! -f "$1" ]; then
echo -e "must provide log *.ctl file including dir path!
Usage:
command some.ctl
command path/to/some.ctl
command /path/to/some.ctl"
exit 1
fi
ctlfile="$1"
rundir=$(dirname $ctlfile)
logbasename=$(basename $ctlfile .ctl)
trap 'kill $(jobs -pr); exit 0' EXIT
oldseq=$(cat $ctlfile)
# as daemon job but sharing stdout with parent
tail -f $rundir/${logbasename}_$oldseq.log &
#jobs
while true
do
newseq=$(cat $ctlfile)
if [ $newseq -eq $oldseq ]; then
sleep 5
else
oldseq=$newseq
# kill first daemon job
kill %%
tail -f $rundir/${logbasename}_$oldseq.log &
fi
done
顺便说一句:此脚本拷贝到/usr/bin下面,且加上执行权限,就可以随时使用 :)