分享一个利用wget的限时、限速下载脚本

有这么一个需求:有一系列图片url(只是url而已)存在文件里(或别的存储里),我需要写一个后台任务程序,把这些url一个个down成图片,因此,需要注意以下几点:
1.如果图片很大(比如超过2M),那么需要在发现后停止下载;
2.如果图片所在网站速度很慢,不能一直等它下完,超时就kill;
3.更高层的程序可能会多进程地调用此脚本来完成并行下载,因此这个脚本最好限个速,保证服务器带宽稳定。

linux下有一个非常好的下载工具wget,直接使用这个工具来帮助完成上述任务能节约开发成本,并且稳定可靠;不过,在看完了man wget后,发现没有办法配置wget使得脚本满足第1条要求(即限制下载大小),貌似沾点边的--quota却对单个下载url是无效的,因此,稍微做了一点shell编程,变通地解决了该问题。
先是下载脚本:

#!/bin/bash

##usage: ./singleDown dirName fileName url
if [ $# -lt 3 ]
then
	echo 'usage: ./singleDown.sh dirName fileName url'
	exit 1
fi
##重试次数
retryTime=3
##等待超时(s)
idleTimeOut=7
##下载限时
downTimeOut=16
##下载限速
limitRate=128k
##每次重试的间隔时间(s)
waitRetry=1

url=`echo "$3" | sed "s/ /%20/g"`
postFix=`echo $url | awk -F. '{print $NF}'`

wget -q -nc --no-cookies --ignore-length -t $retryTime -T $idleTimeOut --limit-rate=$limitRate --waitretry=$waitRetry -O $1/$2.$postFix $url &

downPid=$!
./sleepAndKill.sh $downTimeOut $downPid &
clockPid=$!

wait $downPid
downResult=$?

ps $clockPid
if [ $? -eq 0 ]
then
	kill -9 $clockPid
fi
exit $downResult

这个脚本分析目标url的后缀,根据传入的保存路径和保存文件名,将文件下载下来。
其中,仍然没有下载大小限制的配置,但我们注意到有一个'downTimeOut'和'limitRate',这两个相乘刚好2M,间接地解决了大小限制的问题;
然后这个'downTimeOut'是怎么实现的呢?是通过另一个脚本'sleepAndKill.sh'来实现的(wget中的配置项的所有timeout均指'idle Time',即等待时间,并非'下载时间',所以这个timeout必须另写脚本实现):
#!/bin/bash

##usage: timeOut(s) pidToKill

if [ $# -lt 2 ]
then
	echo 'usage: timeOut(s) pidToKill'
	exit 1
fi

sleep $1
ps $2
if [ $? -eq 0 ]
then
	kill -9 $2
fi


这个脚本很简单,传入timeout和监控的pid,然后sleep,醒来后如果发现pid所代表的进程还在的话就Kill.
在第一个脚本中我们也看到这么一行:

kill -9 $clockPid

这个$clockPid是sleepAndKill.sh的id,也就是说,在运行的时候,下载脚本和sleepAndKill.sh在赛跑,谁先做完事情,就会主动去kill另一方,以保证脚本在尽可能短的时间内跑完:

如果下载脚本在16秒内跑完了(这时sleepAndKill.sh还在睡),就杀掉sleepAndKill.sh,任务结束(不然sleepAndKill.sh还在那傻睡);
如果下载脚本16秒后还没跑完,sleepAndKill.sh醒来,kill掉下载脚本,任务结束,保证不会down下超过2M的图片。

本来还考虑通过content-length来判断是否目标大于2M,不过content-length是不可靠的,且并不比上述方法来得简单。

用法:
./singleDown.sh ./ google http://www.google.cn/intl/zh-CN/images/logo_cn.gif

以上命令将google的logo保存在当前文件夹下,名叫'google.gif'

脚本在附件中。
脚本所调用的wget版本为:'GNU Wget 1.10.2',更古老的版本在加上'&'符号运行时的行为比较奇怪,可能会影响限时功能,不建议使用过于古老版本的wget。

你可能感兴趣的:(编程,linux,Google,脚本,bash)