您尚未登录。

#1 2011-08-21 09:37:03

archblue
会员
注册时间: 2011-08-21
帖子: 49

分享一个arch源同步脚本

主要是在rsync的基础上加了速度检测, 当测试速度低于预测最低值时, 本次同步取消, 否则继续.

#!/bin/bash
#2010.03.05 archlinux同步脚本, 实现基本功能
#2010.05.11 增加自动检测镜像源速度功能, 自动选择最快镜像源同步
#		    基本原理, 分别从各个源同步一个小文件, 然后检测其速度大小, 取最快的那个源.
#		    考虑到源数目过多时, 逐一检测非常耗时, 因而设了一个自选优化值:
#		   	RATE_EXPECT	速度期望值, 若最快速度大于此值, 则不再进行后续检测, 直接使用此镜像源
#		    	若不想启用该条件, 可将之设为0
#		    RATE_MINIMUM	速度下限, 若同步速度低于此值则排除该镜像.以保证有效的最快速度总是大于此值.
#		    MIRROR_FILE为镜像源列表, 支持#注释符
#		    TEST_FILE为待同步的小文件, 本例中选取/extra/os/i686/extra.abs.tar.gz, 因为它的大小只有2M, 即使低速率下载也不会消耗太多时间. 
#2010.05.12 更新速度检测算法, 不再只考虑最后一行, 而改用全局平均速度,以便获得更精确值.
#		    Rsync的结果不能用管道全部传送, 只好调用中间日志文件做重定向
set -x     

MIRROR_FILE="/media/repo/mirror.list"
TEST_FILE="/extra/os/i686/extra.abs.tar.gz"
RATE_MINIMUM=100
RATE_EXPECT=150
FASTMIRROR=""
RATE_FAST="0"

DST="/media/repo/ArchLinux"
EXCLUDE_FILE="/media/repo/exclude.txt"

if [ ! -d $DST ]; then
        mkdir -p $DST
fi

if [ -f /tmp/$(basename $TEST_FILE) ]; then
	  rm /tmp/$(basename $TEST_FILE)
fi

killall rsync

#排除以#开头的内容, 使MIRROR_FILE支持注释功能
for i in $(cat $MIRROR_FILE | sed 's/\#.*$//g' )
do
#获得同步的速度, 注意bash不支持实数型数值比较,因而用awk将之截断,只取整数部分.
#	RATE=$(rsync -avh --progress --timeout=10 $i/$TEST_FILE /tmp/ | sed  -n '/xfer/p' |  sed  -r 's/.*[ ]+(.*)kB\/s.*/\1/g' | awk 'BEGIN{FS="."}{print $1}') 
	rsync -avh --progress --timeout=10 $i/$TEST_FILE /tmp/ > /tmp/log
	RATE=$( cat -A /tmp/log  | sed -n '/kB\/s/p' | sed  's/\^M/\n/g' | sed -r 's/.*[ ]+([0-9.]+)kB\/s.*/\1/g' | awk 'BEGIN{sum=0} {sum=sum+$1} END{if (NR!=0) print sum/NR; else print 0}' | awk 'BEGIN{FS="."}{print $1}' ) 
	rm /tmp/$(basename $TEST_FILE)
#若RATE_MINIMUM开启, 且速度低于RATE_MINIMUM, 则跳到本次循环, 排除该镜像源
	if [ "$RATE_MINIMUM" -gt "0" ] && [ "$RATE" -lt "$RATE_MINIMUM"  ]; then
		continue
	fi
	
#若RATE_EXPECT开启, 且速度大于RATE_EXPECT, 则直接选择该镜像源, 结束循环
	if [ "$RATE_EXPECT" -gt "0" ] && [ "$RATE" -gt "$RATE_EXPECT" ]; then
		FASTMIRROR="$i"
		break
	fi
	
#	若当前速度大于RATE_FAST, 则将值赋与RATE_FAST, 并将当前源设为FASTMIRROR
	if [ "$RATE_FAST" -ge "0" ] && [ "$RATE" -gt "$RATE_FAST" ]; then
		RATE_FAST="$RATE"
		FASTMIRROR="$i"
	fi
	
	#因为需要重复下载该文件, 必须将之删除,否则下次将跳过,不再同步
#	rm /tmp/$(basename $TEST_FILE)
done

#echo "$FASTMIRROR"

#如果FASTMIRROR非空, 则开始同步
if [ -n "$FASTMIRROR" ]; then
        rsync -avh --progress --delete-after --partial --exclude-from=$EXCLUDE_FILE $FASTMIRROR/  $DST/
fi

这是用python改写后的, 二者功能相同.

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#2010.05.15 首次完成,把RsyncFastMirror.sh用python重写
#	    主要功能都已实现, 如测速,注释等

import os
import re
import time

def pyrsync(v,*u):
#u[0] source. u[1] dst. u[2] 可选 exluce file
        if u.__len__()==2:
                cmd0="rsync -avh --progress --timeout=10 "+u[0]+" "+u[1]
                print("cmd0=",cmd0)
        cs=os.popen(cmd0).readlines()
        par=re.compile("[0-9.]+kB/s")
        for line in cs:
             if par.search(line):
                  v.append(line)
        return v

	
def pyrate(v):
	sum=0
	for i in v:
		print(i.split()[2].strip("kB/s"))
		sum+=float(i.split()[2].strip("kB/s"))
#	print(sum)  
	if v.__len__() > 0:
		return sum/v.__len__()
	else:
		return 0
#	print("averg=",sum/v.__len__())
	
def file_comment(flist):
	pat=re.compile("#.*$")
	pat2=re.compile("^[ \t]+$")
	for i in range(flist.__len__()):
		if pat.search(flist[i]):
			flist[i]=pat.sub("",flist[i])
		if pat2.search(flist[i]):
			flist.pop(i)
	return flist
	

if __name__ == "__main__":
	MIRROR_FILE="/media/repo/mirror.list"
	TEST_FILE="/extra/os/i686/extra.abs.tar.gz"
	RATE_MINIMUM=100
	RATE_EXPECT=150
	FASTMIRROR=""
	RATE_FAST=0
	
	DST=r"/media/repo/ArchLinux/"
	EXCLUDE_FILE="/media/repo/exclude.txt"

	tmp_file=os.path.join("/tmp",TEST_FILE.split("/")[-1])
	cmd1="rm -f "+tmp_file
	if os.path.exists(tmp_file):
		os.system(cmd1)
	
	print("The Time is :",time.ctime())
	f=file_comment(open(MIRROR_FILE,"r").readlines())
	for line in f:
	   if line !="":
	        u=[]
	        avg=0.0
	        print("line=",line)
	        cmd2=line.strip().rstrip("/")+"/"+TEST_FILE
	        print("cmd2=",cmd2)
	        pyrsync(u,cmd2,"/tmp")
#	        print(u)
#	        print(line)
	        avg=pyrate(u)
	        print("avg=",avg)
	        if RATE_MINIMUM >0 and avg < RATE_MINIMUM :
	                continue
	        if RATE_EXPECT >0 and avg >RATE_EXPECT :
		        FASTMIRROR=line
		        break
	        if RATE_FAST >=0 and avg >RATE_FAST :
		        RATE_FAST=avg
		        FASTMIRROR=line
		        print(avg,FASTMIRROR)
	        os.system(cmd1)

	print(FASTMIRROR)
	if FASTMIRROR !="" :
		cmd0="rsync -avh --progress --timeout=10 --delete-after --exclude-from="+EXCLUDE_FILE+" "+FASTMIRROR.strip()+"/ "+DST
#		print(type(cmd0),len(cmd0))
		print(cmd0.replace("\n",""))
		os.system(cmd0.replace("\n",""))

离线

#2 2011-08-21 15:35:38

SmallV
会员
注册时间: 2011-08-19
帖子: 146

Re: 分享一个arch源同步脚本

wp.png

离线

#3 2011-08-21 19:17:09

月下叹逍遥
论坛版主
注册时间: 2011-08-19
帖子: 138
个人网站

Re: 分享一个arch源同步脚本

lz好签名…… :em38

离线

#4 2011-08-21 19:29:16

jtshs256
论坛版主
注册时间: 2011-08-19
帖子: 294

Re: 分享一个arch源同步脚本

这签名……住的楼号错了也就算了,邮编错了也就算了,竟然谎报温度……怎么可能15-8度嘛…… :em20
话说哪天会不会弃 rsync 用 git 呢?……

离线

#5 2011-08-22 18:13:19

SmallV
会员
注册时间: 2011-08-19
帖子: 146

Re: 分享一个arch源同步脚本

jtshs256 说:

这签名……住的楼号错了也就算了,邮编错了也就算了,竟然谎报温度……怎么可能15-8度嘛…… :em20
话说哪天会不会弃 rsync 用 git 呢?……

连楼号也报?好怕怕…… :em34

离线

#6 2011-08-22 18:47:49

YeLee
BOT
注册时间: 2011-08-19
帖子: 661

Re: 分享一个arch源同步脚本

SmallV 说:
jtshs256 说:

这签名……住的楼号错了也就算了,邮编错了也就算了,竟然谎报温度……怎么可能15-8度嘛…… :em20
话说哪天会不会弃 rsync 用 git 呢?……

连楼号也报?好怕怕…… :em34

:em70  :em70  :em70


小白路过,大家给点面子!

离线

#7 2011-08-24 02:02:34

ReiFFEXzyx
古悠行者
注册时间: 2011-08-20
帖子: 187

Re: 分享一个arch源同步脚本

总感觉显IP签名这玩意不安全

反正我是会在hosts中把它们的ip禁掉

#蜗图拉个性动态iP签名
0.0.0.0 i.wotula.com
0.0.0.0 ip.wotula.com
0.0.0.0 www.godiy8.com


[fracting的大作]Wine使用中的一些常见误区
http://forum.ubuntu.org.cn/viewtopic.php?f=121&t=363147
顺便学习一下对待开源软件的正确态度

离线

页脚