LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 1181|回复: 10

分享一个arch源同步脚本

[复制链接]
发表于 2011-6-21 11:47:32 | 显示全部楼层 |阅读模式
因为有时源rsync速度不行, 太慢的话不如不同步, 所以下面大部分代码是做测速功能的.  



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

  14. MIRROR_FILE="/media/repo/mirror.list"
  15. TEST_FILE="/extra/os/i686/extra.abs.tar.gz"
  16. RATE_MINIMUM=100
  17. RATE_EXPECT=150
  18. FASTMIRROR=""
  19. RATE_FAST="0"

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

  22. if [ ! -d $DST ]; then
  23.         mkdir -p $DST
  24. fi

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

  28. killall rsync

  29. #排除以#开头的内容, 使MIRROR_FILE支持注释功能
  30. for i in $(cat $MIRROR_FILE | sed 's/\#.*$//g' )
  31. do
  32. #获得同步的速度, 注意bash不支持实数型数值比较,因而用awk将之截断,只取整数部分.
  33. #        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}')
  34.         rsync -avh --progress --timeout=10 $i/$TEST_FILE /tmp/ > /tmp/log
  35.         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}' )
  36.         rm /tmp/$(basename $TEST_FILE)
  37. #若RATE_MINIMUM开启, 且速度低于RATE_MINIMUM, 则跳到本次循环, 排除该镜像源
  38.         if [ "$RATE_MINIMUM" -gt "0" ] && [ "$RATE" -lt "$RATE_MINIMUM"  ]; then
  39.                 continue
  40.         fi
  41.        
  42. #若RATE_EXPECT开启, 且速度大于RATE_EXPECT, 则直接选择该镜像源, 结束循环
  43.         if [ "$RATE_EXPECT" -gt "0" ] && [ "$RATE" -gt "$RATE_EXPECT" ]; then
  44.                 FASTMIRROR="$i"
  45.                 break
  46.         fi
  47.        
  48. #        若当前速度大于RATE_FAST, 则将值赋与RATE_FAST, 并将当前源设为FASTMIRROR
  49.         if [ "$RATE_FAST" -ge "0" ] && [ "$RATE" -gt "$RATE_FAST" ]; then
  50.                 RATE_FAST="$RATE"
  51.                 FASTMIRROR="$i"
  52.         fi
  53.        
  54.         #因为需要重复下载该文件, 必须将之删除,否则下次将跳过,不再同步
  55. #        rm /tmp/$(basename $TEST_FILE)
  56. done

  57. #echo "$FASTMIRROR"

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

复制代码


我常用的二个mirror是

  1. rsync://mirrors.kernel.org/archlinux/
  2. rsync://ftp.jaist.ac.jp/pub/Linux/ArchLinux
复制代码

写入MIRROR_FILE就ok了

另外还有一个python版本, 功能等价

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

  5. import os
  6. import re
  7. import time

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

  19.        
  20. def pyrate(v):
  21.         sum=0
  22.         for i in v:
  23.                 print(i.split()[2].strip("kB/s"))
  24.                 sum+=float(i.split()[2].strip("kB/s"))
  25. #        print(sum)  
  26.         if v.__len__() > 0:
  27.                 return sum/v.__len__()
  28.         else:
  29.                 return 0
  30. #        print("averg=",sum/v.__len__())
  31.        
  32. def file_comment(flist):
  33.         pat=re.compile("#.*$")
  34.         pat2=re.compile("^[ \t]+$")
  35.         for i in range(flist.__len__()):
  36.                 if pat.search(flist[i]):
  37.                         flist[i]=pat.sub("",flist[i])
  38.                 if pat2.search(flist[i]):
  39.                         flist.pop(i)
  40.         return flist
  41.        

  42. if __name__ == "__main__":
  43.         MIRROR_FILE="/media/repo/mirror.list"
  44.         TEST_FILE="/extra/os/i686/extra.abs.tar.gz"
  45.         RATE_MINIMUM=100
  46.         RATE_EXPECT=150
  47.         FASTMIRROR=""
  48.         RATE_FAST=0
  49.        
  50.         DST=r"/media/repo/ArchLinux/"
  51.         EXCLUDE_FILE="/media/repo/exclude.txt"

  52.         tmp_file=os.path.join("/tmp",TEST_FILE.split("/")[-1])
  53.         cmd1="rm -f "+tmp_file
  54.         if os.path.exists(tmp_file):
  55.                 os.system(cmd1)
  56.        
  57.         print("The Time is :",time.ctime())
  58.         f=file_comment(open(MIRROR_FILE,"r").readlines())
  59.         for line in f:
  60.            if line !="":
  61.                 u=[]
  62.                 avg=0.0
  63.                 print("line=",line)
  64.                 cmd2=line.strip().rstrip("/")+"/"+TEST_FILE
  65.                 print("cmd2=",cmd2)
  66.                 pyrsync(u,cmd2,"/tmp")
  67. #                print(u)
  68. #                print(line)
  69.                 avg=pyrate(u)
  70.                 print("avg=",avg)
  71.                 if RATE_MINIMUM >0 and avg < RATE_MINIMUM :
  72.                         continue
  73.                 if RATE_EXPECT >0 and avg >RATE_EXPECT :
  74.                         FASTMIRROR=line
  75.                         break
  76.                 if RATE_FAST >=0 and avg >RATE_FAST :
  77.                         RATE_FAST=avg
  78.                         FASTMIRROR=line
  79.                         print(avg,FASTMIRROR)
  80.                 os.system(cmd1)

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

复制代码
发表于 2011-6-21 12:30:53 | 显示全部楼层
感谢分享,还没同步过arch的包,应该有好几个G吧
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-6-21 13:15:53 | 显示全部楼层
看你同步多少了,
我是排除源码码和iso
包括32位和64位, 大概30G
排除掉游戏, 在22G左右
如果只同步一个版本, 可能还要小点
回复 支持 反对

使用道具 举报

发表于 2011-6-21 13:31:46 | 显示全部楼层
同步一个仓库太大了,一般都是把本地的/var/cache/pacman/pkg 共享出来,然后局域网的其他机器来用这上面的包,一般几台机子安的软件都差不多就直接可用,发现本地仓库没有再从网上下载
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-6-21 13:38:08 | 显示全部楼层
相对来说, arch的源算小的了
fedora一个32位源就有30G了
/var/cache/pacman/pkg里的包毕竟不全
如果要省空间的话, 可人只同步core, extra, community三个
然后在rsync里加入选项, 把软连接替换为真实文件
因为后二者中有太多的软连接, 所以没法告许你真实大小.
回复 支持 反对

使用道具 举报

发表于 2011-6-21 22:59:17 | 显示全部楼层
Post by archblue;2143011
看你同步多少了,
我是排除源码码和iso
包括32位和64位, 大概30G
排除掉游戏, 在22G左右
如果只同步一个版本, 可能还要小点


我同步了32位的core、extra、community就22G了。。。
怎么排除游戏?
对于any(x86、64共用)的包怎样才能用链接呢?
我同步下来都是两独立的文件,加了rsync的链接的参数也不行
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-6-21 23:25:53 | 显示全部楼层
Post by 战雨灾;2143067
我同步了32位的core、extra、community就22G了。。。
怎么排除游戏?
对于any(x86、64共用)的包怎样才能用链接呢?
我同步下来都是两独立的文件,加了rsync的链接的参数也不行

rsync可以指定排除文件的 --exclude-from=file, 附件是我用的排除文件
any包没法不下载吧
可以到本地镜像目录, 运行
  1. du -a -h | sort -h -k1 | sed -n '/pkg\.tar/p'
复制代码
看看最大的几个文件都是什么, 是不是游戏文件

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x
回复 支持 反对

使用道具 举报

发表于 2011-6-22 08:37:29 | 显示全部楼层
Post by archblue;2143069
rsync可以指定排除文件的 --exclude-from=file, 附件是我用的排除文件
any包没法不下载吧
可以到本地镜像目录, 运行

  1. du -a -h | sort -h -k1 | sed -n '/pkg\.tar/p'
复制代码

看看最大的几个文件都是什么, 是不是游戏文件


排除游戏是排除几个大的游戏文件吗,我还以为全部游戏都排除了(像排除64位在file里加一行*/os/x86_64)
我的意思不是不下载,而是不重复下载any包

我看服务器上的文件,如果any包是x86、64共用的,则放到any文件夹,然后在x86和64两个文件夹里链接到any文件夹的文件。
还有很多文件链接到了pool文件夹。
----
PS:sort 在 msys 环境下没 -h 参数,不知道是不是 archlinux 下有的
回复 支持 反对

使用道具 举报

 楼主| 发表于 2011-6-22 11:50:56 | 显示全部楼层
因为游戏名也是我自己找的, 全部都看一遍太难了
只好优先屏蔽大包
any包都是软连接, 不会重复下载的, 只有一个是真实文件, 其它的都是连接而已
pool里存放了大部分真实文件, core, community, extra里很多都只是连接而已. 当然pool里也包括了testing的东西, 内容要比前三者之和大得多
回复 支持 反对

使用道具 举报

发表于 2011-6-23 09:14:19 | 显示全部楼层
狂汗,我把之前用的脚本上rsync的 -lH --copy-links --safe-links参数去掉下载下来的就是链接了,这几个参数的意思不是保持链接吗?
----
PS:笔记本电没插好,电池用到爆,一下子去了五分一的损耗,有什么办法没
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表