之前一直利用VPS 手动下载一下zip 的文件再利用百度云网盘的离线下载功能同步至国内网盘,期间还需要检查zip文件的完整性,再区别文件名上传至不同的百度云网盘中,综合起来需要手动处理的流程大概是这样的:

获取zip 文件下载地址 -> ssh 登陆到VPS建立下载任务 -> 不定时检查任务下载进度 -> 下载完成后获取zip 文件属性(预览及md5 校验) -> 登陆1号百度云建立离线任务 -> 登陆2号百度云建立离线任务。

通过linux 的inotify 东拼西凑写了个shell脚本,自动处理后简化任务为:

获取zip 文件下载地址 -> ssh 登陆到VPS 建立下载任务

后面的几个繁琐步骤已实现自动完成,大大省掉了人力成本,效率高了不是一点点呢。但是搞这个小脚本竟然超时那么多,明显非常不谨慎,该反思… 任务耗时

检查内核是否支持inotify 特性:

由于inotify特性需要Linux内核的支持,确认Linux系统内核是否达到了2.6.13以上,如果Linux内核低于2.6.13版本,就需要重新编译内核加入inotify的支持,也可以用如下方法判断,内核是否支持inotify:

1
2
root@uxbaztjwv4:~# uname -r
2.6.32-042stab088.4
1
2
3
4
5
6
7
root@uxbaztjwv4:~# ll /proc/sys/fs/inotify/
total 0
dr-xr-xr-x 0 root root 0 Jul 10 00:56 ./
dr-xr-xr-x 0 root root 0 Jun 17 00:09 ../
-rw-r--r-- 1 root root 0 Jul 10 00:56 max_queued_events
-rw-r--r-- 1 root root 0 Jul 10 00:56 max_user_instances
-rw-r--r-- 1 root root 0 Jul 10 00:56 max_user_watches

如果有上面三项输出,表示系统已经默认支持inotify,接着就可以开始安装inotify-tools了。 安装inotify-tools: inotify-tools 是为linux下inotify文件监控工具提供的一套c的开发接口库函数,同时还提供了一系列的命令行工具,这些工具可以用来监控文件系统的事件。 inotify-tools是用c编写的,除了要求内核支持inotify外,不依赖于其他。inotify-tools提供两种工具,一是inotifywait,它是用来监控文件或目录的变化,二是inotifywatch,它是用来统计文件系统访问的次数。 由于个人使用的server 系统为ubuntu

1
2
root@uxbaztjwv4:~# cat /etc/issue
Ubuntu 12.04.4 LTS

所以安装inotify-tools 的过程尤为简单,仅是apt-get install inotify-tools 就结束。其他发行版同样可以到github clone 下来进行编译安装。这是主页:https://github.com/rvoicilas/inotify-tools

创建inotify 监控任务 mon.sh:

1
2
3
4
5
6
7
8
#!/bin/bash

export CNROMS_SRC=/home/tmp/ # direcotory to monitor
inotifywait --exclude '\.(part|swp)' -mq -e create,delete,move,close_write $CNROMS_SRC |
while read event;
do
./action.sh
done

事件发生后执行任务的子进程action.sh:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
#!/bin/bash

FILES=`find $CNROMS_SRC -maxdepth 1 -type f -regextype "posix-egrep" -regex ".*(AAA|BBB|CCC).*\.zip$" -print;` # 通过扩展find 正则,在目录深度为1 的目录中匹配AAA(或BBB 或CCC )字符串的文件列表并打印
#FILES=`ls $CNROMS_SRC | grep -E '^(AAA|BBB|CCC).*\.zip$'`
#echo $FILES
#sleep 1

if [ -n "$FILES" ]; then # 判断变量$FILES 以否有值,如果有则执行

CNROMS_SRC="/home/tmp"
OUTPATH="/home/www/pending.html" # 定义脚本执行结果的输出文件
cat /dev/null > $OUTPATH # 清空文件内容,以下填充一些基本的html 标签
echo "<html><head><title>ROMS Detail</title></head><body>" >> $OUTPATH
echo 'New file has been detected, your program is working in process. Click [here to have a look.' > /home/www/index.html
echo -n "<a href='/tmp/'>ROMS info</a> generated by action.sh at " >> $OUTPATH
date >> $OUTPATH

echo "<ul>" >> $OUTPATH
for FILE in $FILES # 文件循环处理开始
do
REGION=`echo ${FILE:10:3}` # 截取结果中的第10位开始长度为3的字符串
# if [ $REGION = "AAA" -o $REGION = "BBB" -o $REGION = "CTC" ]; then
# AREA="CN"
# mv $FILE $CNROMS_SRC/$AREA
# elif [ $REGION = "CCC" ]; then
# AREA="HK"
# mv $FILE $CNROMS_SRC/$AREA
# fi
case $REGION in # 匹配AAA、BBB、CCC,做相应的处理
AAA|BBB)
AREA_DEFAULT="CN" # 定义区域变量以移动匹配了AAA、BBB 的文件到相应子目录下
mv $FILE $CNROMS_SRC/$AREA_DEFAULT/
# FILE="${FILE:+$CNROMS_SRC/$AREA/$FILE}"
# OutPut $FILE
;;
CCC)
AREA_CNROMS="HK" # 定义区域变量以移动匹配了CCC 的文件到相应子目录下
mv $FILE $CNROMS_SRC/$AREA_CNROMS/
# FILE="${FILE:+$CNROMS_SRC/$AREA/$FILE}"
# OutPut $FILE
;;
*)
break
;;
esac
# if [ "$REGION"x = "CCC"x ]; then
# mv $CNROMS_SRC/$FILE $CNROMS_SRC/HK/
# echo $REGION
# fi
done
#ls $CNROMS_SRC | grep -E '^(AAA|BBB|CTC).*\.zip$' | xargs -i mv $CNROMS_SRC/{} $CNROMS_SRC/CN/
#OutPut $FILES

ROMS=`find $CNROMS_SRC -mindepth 2 -type f -regextype "posix-egrep" -regex ".*(AAA|BBB|CCC).*\.zip$" -print;` # 检查子目录匹配AAA(或BBB 或CCC )字符串的文件列表并打印
#sleep 1
for ROM in $ROMS # 循环打印各zip 压缩包的内容及md5 校验结果
do
echo "<li><pre>" >> $OUTPATH
unzip -v $ROM >> $OUTPATH
# unzip -v $1 >> $OUTPATH
echo -n "<p>MD5: " >> $OUTPATH
md5sum $ROM >> $OUTPATH
echo "</p>" >> $OUTPATH
echo "</pre>></li>" >> $OUTPATH
done
echo "</ul>" >> $OUTPATH

# Check bypy.py

bypy_COUNT="`ps -ef|grep bypy.py | grep -v 'grep' | wc -l`" # 检查后台是否存在百度云同步程序(bypy)运行
if [ $bypy_COUNT -eq 0 ]; then # 如果后台没有bypy.py 程序运行,开始执行系列的同步操作
echo "<hr /><p>=>>
Sync processing...</p><div style='overflow: scroll; height: 300px;'>" >> $OUTPATH
# python ~/Studio/python/bypy/bypy.py -v syncup /home/tmp/CN/ >> $OUTPATH &
# python ~/Studio/python/bypy-cnroms/bypy.py -v syncup /home/tmp/HK/ >> $OUTPATH &
if [ -n "$AREA_DEFAULT" ] && [ -n "$AREA_CNROMS" ]; then # 检查之前的区域变量是否有值,主要是为了做分类,上传至不同的百度云网盘中,以下if 作用基本相同
echo "<p>=>> Sync 'CN' and 'HK' folders.</p>" >> $OUTPATH
python ~/Studio/python/bypy/bypy.py -v syncup /home/tmp/CN/ >> $OUTPATH &
python ~/Studio/python/bypy-cnroms/bypy.py -v syncup /home/tmp/HK/ >> $OUTPATH &
wait
mv /home/tmp/CN/* /home/tmp/HK/* /home/tmp/useless/
elif [ -n "$AREA_DEFAULT" ] && [ -z "$AREA_CNROMS" ]; then
echo "<p>=>> Sync 'CN' folder only.</p>" >> $OUTPATH
python ~/Studio/python/bypy/bypy.py -v syncup /home/tmp/CN/ >> $OUTPATH &
wait
mv /home/tmp/CN/* /home/tmp/useless/
elif [ -n "$AREA_CNROMS" ] && [ -z "$AREA_DEFAULT" ]; then
echo "<p>=>> Sync 'HK' folder only.</p>" >> $OUTPATH
python ~/Studio/python/bypy-cnroms/bypy.py -v syncup /home/tmp/HK/ >> $OUTPATH &
wait
mv /home/tmp/HK/* /home/tmp/useless/
fi
wait
echo "</div><p>=>> Jobs done.</p>" >> $OUTPATH # 等待所有后台进程完成后,输出!
fi


echo "</body></html>" >> $OUTPATH
cat $OUTPATH > /home/www/index.html # 将所有完整的处理结果重定向至web 服务主页文件,方便通过web 验收!
echo "Sorry guys, there's nothing left here, maybe you should take a rest." > $OUTPATH

fi

# 定义了一个空函数,作用待开发
#Compare()
#{
#}](/pending.html)

启动监控进程并保持后台运行:

1
nohup ~/Studio/sh/mon.sh &

inotifywait 及 inotifywatch 的参数、使用语法

我在《inotify-tools命令使用讲解》搬来一些供参考:

inotifywait 语法: inotifywait [-hcmrq] [-e ] [-t ] [–format ] [–timefmt ] [ … ]

参数:

-h,–help 输出帮助信息
@ 排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile 从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-m, –monitor 接收到一个事情而不退出,无限期地执行。默认的行为是接收到一个事情后立即退出。
-d, –daemon 跟–monitor一样,除了是在后台运行,需要指定–outfile把事情输出到一个文件。也意味着使用了–syslog。
-o, –outfile 输出事情到一个文件而不是标准输出。
-s, –syslog 输出错误信息到系统日志 -r, –recursive 监视一个目录下的所有子目录。
-q, –quiet 指定一次,不会输出详细信息,指定二次,除了致命错误,不会输出任何信息。
–exclude 正则匹配需要排除的文件,大小写敏感。
–excludei 正则匹配需要排除的文件,忽略大小写。
-t , –timeout 设置超时时间,如果为0,则无限期地执行下去。
-e , –event 指定监视的事件。
-c, –csv 输出csv格式。
–timefmt 指定时间格式,用于–format选项中的%T格式。
–format 指定输出格式。 %w 表示发生事件的目录 %f 表示发生事件的文件 %e 表示发生的事件 %Xe 事件以“X”分隔 %T 使用由–timefmt定义的时间格式

inotifywatch 语法: inotifywatch [-hvzrqf] [-e ] [-t ] [-a ] [-d ] [ … ]

参数:

-h, –help 输出帮助信息
-v, –verbose 输出详细信息
@ 排除不需要监视的文件,可以是相对路径,也可以是绝对路径。
–fromfile 从文件读取需要监视的文件或排除的文件,一个文件一行,排除的文件以@开头。
-z, –zero 输出表格的行和列,即使元素为空
–exclude 正则匹配需要排除的文件,大小写敏感。
–excludei 正则匹配需要排除的文件,忽略大小写。
-r, –recursive 监视一个目录下的所有子目录。
-t , –timeout 设置超时时间
-e , –event 只监听指定的事件。
-a , –ascending 以指定事件升序排列。
-d , –descending 以指定事件降序排列。

可监听事件

access

文件读取

modify

文件更改。

attrib

文件属性更改,如权限,时间戳等。

close_write

以可写模式打开的文件被关闭,不代表此文件一定已经写入数据。

close_nowrite

以只读模式打开的文件被关闭。

close

文件被关闭,不管它是如何打开的。

open

文件打开。

moved_to

一个文件或目录移动到监听的目录,即使是在同一目录内移动,此事件也触发。

moved_from

一个文件或目录移出监听的目录,即使是在同一目录内移动,此事件也触发。

move

包括moved_to和moved_from

move_self

文件或目录被移除,之后不再监听此文件或目录。

create

文件或目录创建

delete

文件或目录删除

delete_self

文件或目录移除,之后不再监听此文件或目录

unmount

文件系统取消挂载,之后不再监听此文件系统。

Comments

2014-07-10