今天没事想起前几天新闻组上讨论的一个问题,就是上一篇文章的内容。开始些的autocp.sh脚本用手工执行的方法确实可以成功。但是转到crontab下去执行,就出了问题了,始终无法成功。这个问题困扰了我一天了,现在终于解决了。现在就做个总结吧:
题目是这样说的:
一个目录下有一些以省名+日期为名字的日志文件,这个文夹下的日志文件每天更新,
现要把这个文件夹下的文件,每天自动执行一次将日志文件移动到各省对应的用户目录下/home/along/code/shell/shell/省名/下.
应该如何实现?
首先在我的/home/along/code/shell/shell/finddata目录下有这样的文件(也就是需要进行处理的日志文件):
along@along-laptop:~/code/shell/shell$ ls -l finddata
总用量 12
-rw-r--r-- 1 along along 23 2009-07-20 12:19 henam_9087
-rw-r--r-- 1 along along 22 2009-07-20 12:19 shanghai_467
-rw-r--r-- 1 along along 26 2009-07-20 12:19 xian_890
我的autocp.sh脚本:
#!/bin/bash
#Scriptname:autocopy.sh
#从finddata文件下读取文件名存放在name变量中
#从name中提取对应文件的省名
#SourcePath源文件的地址
#AimPath目标地址
SourcePath="/home/along/code/shell/shell/finddata"
AimPath="/home/along/code/shell/shell/findgod"
name=`ls -l $SourcePath | awk '{print $8}'`
for i in $name
do
#locat:提取文件对应的省份的名字
locat=`expr $i : '(.*)_[0-9].*'`
pathname=`echo $AimPath"/"$locat`
if [ ! -d $pathname ]
then
mkdir $pathname
fi
filename=`echo $SourcePath"/"$i`
cp $filename $pathname
done
#echo "Success Copy!"
exit 0
我写了一个crontab文件:alongcron
along@along-laptop:~/code/shell/shell$ crontab -l
*/1 * * * * /bin/bash /home/along/code/shell/shell/autocp.sh
现在是让他每分钟执行一次。
结果执行之后没有反应。查看邮件信息:
To: along@along-laptop
Subject: Cron /home/along/code/shell/shell/ha.sh
Date: Mon, 20 Jul 2009 15:39:01 +0800
cp: cannot stat `/home/along/code/shell/shell/finddata/12:19': No such file or directory
cp: cannot stat `/home/along/code/shell/shell/finddata/12:19': No such file or directory
cp: cannot stat `/home/along/code/shell/shell/finddata/12:19': No such file or directory
注意观察邮件信息红色部分:本来应该是文件名这时却是是文件的创建时间。发现这里问题出在文件名截取部分。结果将脚本文件中红色部分的 $8 改为 $9,再用crontab执行,问题解决了。
我将脚本文件中的红色部分改为:`ls -l $SourcePath | awk '{print $8}'`>/tem/tmpfile;exit
然后执行后查看/tmp/tmpfile文件发现:
along@along-laptop:/tmp$ cat tmpfile
12:19
12:19
12:19
果然,这里截取的是文件的创建时间。
总结:在crontab中,对字符串的截取第一字段对应的是 $0
在一般模式下,对字符串的截取地一字段对应的是 $1
所以这个脚本要是用cron定时执行,那么脚本中间的红色部分应该是
name=`ls -l $SourcePath | awk '{print $8}'`
要是用手工执行的话,那么脚本中的红色部分应该是:
name=`ls -l $SourcePath | awk '{print $9}'`
就这么一个小问题,我从早上起床一直改到现在,终于找出了问题所在。花了我整整一天的时间啊!!
不过今天学会了利用系统邮件信息,输入mail就可以查看了。同时也可以通过重定向将邮件信息发送到指定的文件。比如 下面这个就是将邮件信息和出错信息全部重定向到指定的文件这样查看起来就更方便了。
*/1 * * * * /bin/bash /home/along/code/shell/shell/autocp.sh > /tmp/mailfile 2>&1
下面是这个autocp的另外两种实现方法(这里就不涉及$8和$9的问题了):
方法一:
将
name=`ls -l $SourcePath | awk '{print $9}'`
改为:
name=`ls $SourcePath`
这里其实不用awk截取文件名的。我之前总是想的是用ls -l 命令。
方法二:
#!/bin/bash
#Scriptname:autocopy.sh
#从finddata文件下读取文件名存放在name变量中
#从name中提取对应文件的省名
#SourcePath源文件的地址
#AimPath目标地址
#这是另外一种实现方法
SourcePath="/home/along/code/shell/shell/finddata"
AimPath="/home/along/code/shell/shell/findgod"
#主要是下边这里直接切换到SourcePath下操作会更方便
cd $SourcePath
for filename in *
do
#locat:提取文件对应的省份的名字
locat=`expr $filename : '\(.*\)_[0-9].*'`
pathname=`echo $AimPath"/"$locat`
if [ ! -d $pathname ]
then
mkdir $pathname
fi
cp $filename $pathname
done
#echo "Success Copy!"
exit 0
阅读(2758) | 评论(0) | 转发(0) |