shell脚本扫描多层目录并获取该目录下的最新文件
需求:因为涉及到数据备份,两个服务器之间的数据备份之后要定期检查备份情况,备份情况要细分为备份任务的完成度和备份数据的完整性
本文主要是设计如何快速检查备份数据的完整性。
因为我这里的备份任务不是实时执行,所以具有一定的时间差,由A服务器备份到B服务器,如果要对比数据备份的完整性,最好的办法就是找到B服务器上的最新的文件,文件大小和A服务器上最新的文件做对比,大小一致,说明数据基本备份完成。
那么如何在这么多备份数据中找到最新的文件就成了一个突破口!
找到了方向那就开始写脚本吧!
需要考虑的是两个方面:如何扫描位置目录结构的深层目录;如何对扫描出来的文件按照时间排序。
不知道目录结构深度,怎么弄呢,我想到了递归函数。
如何排序呢,一开始查找了很多资料,发现ls -t 最管用。反正只是查看文件最后的保存时间(即数据经过改动后的时间),我又不查文件创建时间等。
一开始想到一种方法,可以参考:
这里拿/var/log/目录当小白鼠吧。
#!/bin/bash
# 定义一个找出文件而非目录的函数
function get_dir(){
for i in $1/*
do
if [ -d $i ]; then
# 如果是目录,继续调用函数进行递归操作
get_dir $i
else
# 因为可能存在空目录的情况,所以要加一层判断
if [ ! "`ls -A $i`" == "" ]; then
echo "$i"
fi
fi
done
}
# 定义一个数组来存放函数扫描出来的文件
declare -a file_list=(
`get_dir "/var/log"`
)
# 定义一个数组来存放经过排序的文件
declare -a file_time_list=(
`ls -t ${file_list[@]}`
)
# ls -t 会把最新的文件放在第一个,打印数组里的第一个元素即为这个目录下最新的文件
echo ${file_time_list[0]}
上面这个脚本执行结果发现,空目录尽管加了判断,空目录会显示找不到文件,且后面有*
号,原因是因为,函数里有个*
号,会导致第二个数组里的ls访问失败。。。。。。。。。虽然不影响最后的结果,但是看着这个报错让人很不爽啊。
ls: 无法访问'/var/log/dist-upgrade/*': 没有那个文件或目录
ls: 无法访问'/var/log/samba/cores/nmbd/*': 没有那个文件或目录
ls: 无法访问'/var/log/samba/cores/smbd/*': 没有那个文件或目录
ls: 无法访问'/var/log/shinken/*': 没有那个文件或目录
ls: 无法访问'/var/log/speech-dispatcher/*': 没有那个文件或目录
ls: 无法访问'/var/log/upstart/*': 没有那个文件或目录
ls: 无法访问'/var/log/watchdog/*': 没有那个文件或目录
ls: 无法访问'/var/log/wpslog/*': 没有那个文件或目录
/var/log/syslog
于是,我决定沿用之前的思路,但是略加修改有了下面这个脚本:
#!/bin/bash
# 定义一个找出文件而非目录的函数,这回这里面就不会有*号了吧,必须不能有!
function list_dir(){
for i in `ls $1`
do
# 常规调用函数,进行递归操作
if [ ! -d $1/$i ]; then
echo $1/$i
else
list_dir $1/$i
fi
done
}
# list_dir "/var/log"
# 常规定义数组存放函数获取的文件
declare -a file_list=(
`list_dir "/var/log"`
)
# 常规定义数组进行排序
declare -a file_time_list=(
`ls -t ${file_list[@]}`
)
# 常规获取结果
echo ${file_time_list[0]}
结果如下:
/var/log/syslog
至此,我觉得大功告成。