网速10K以上的,就不要进来参和了,减少对服务器的连接数[做小白要厚道]。
第一部分: 多线程 update ,下载软件列表
首先需要把服务器那边的包的列表拉回来,系统才知道哪个文件升级了。
我的思路是:
1:用工具将服务器那边的文件统统取到本地[多线程]。
2:在本地建立一个最小的镜像站点。
3:将源指向本地,update,速度当然就快了。
下面开始一步一步说明:
1: 我写了个简单的脚本如下。 注:我现在只开了一个官方的源[保证软件最新最鲜],而且只去二进制文件,不取源代码。所以我的sources.list 只有一行:
代码: 全选
deb http://archive.ubuntu.com/ubuntu/ hardy main restricted universe mulitiverse
代码: 全选
#/bin/sh
#服务器的根地址,与 sources.list 里面那个地址的前半段一致。
DIST_URL=http://archive.ubuntu.com/
#CPU架构
DIST_ARCH=i386
#需要安装的包的类型,四个都写上吧
DIST_REPO="main multiverse universe restricted"
#服务器的目录
DIST_DIR=ubuntu/dists/hardy/
#本地保存的位置:放在这里是为了给apache2假设站点用。需要注意有合适的权限。
LOCAL_DIR=/var/www/
#进入本地目录
cd ${LOCAL_DIR}
#函数:取得某个子目录下面的文件, 带一个目录参数,比如 get_sub_dir main
get_sub_dir(){
echo handling $1 ...
TMP_DIR=$1/binary-${DIST_ARCH}/
#将之前存在的目录统统删除,免得 axel 发现已经存在相同文件名后,取下来的文件会带 .0 .1 之类讨厌的后缀。
rm -rf ${TMP_DIR}
mkdir -p ${TMP_DIR}
cd ${TMP_DIR}
#多线程去拉软件列表, 10 可以改小一点。
axel -n 10 ${DIST_URL}${DIST_DIR}${TMP_DIR}Packages.bz2
}
#函数:刷新软件列表,其实就是循环调用上面的 get_sub_dir,分别取得 main multiverse restricted universe 四个目录的内容
refresh_package_list(){
for repo in ${DIST_REPO} ; do
cd ${LOCAL_DIR}${DIST_DIR}
get_sub_dir ${repo}
done
}
#如果之前已经有 ${DIST_DIR} 目录了,提醒一下
if [ -d ${DIST_DIR} ]; then
echo dir: ${LOCAL_DIR}${DIST_DIR} already exists.
fi
#如果还没有,那么提醒并自动创建
if [ ! -d ${DIST_DIR} ] ; then
echo "dir: ${LOCAL_DIR}${DIST_DIR} not exists, will create it."
mkdir -p ${DIST_DIR}
fi
#进入目录,相当于 cd /var/www/ubuntu/dists/hardy
cd ${DIST_DIR}
#函数:wget 单线程取一个文件,如果之前存在,删除之。
wget_file(){
if [ -f $2 ]; then
rm $2
fi
wget $1$2
}
#获取 Release 文件,里面有本Release的时间。这个文件很小,所以单线程。
#这里会先给你看看本地原来的Release[如果有的话]里面的时间,让你知道你现在的这个是什么时间更新的
#如果觉得没有必要,那么就不进行后面的更新了。
if [ -f Release ]; then
echo "Release file exists, and Date is :"
grep Date: Release
echo
echo -n "Are you going to continue ?[y/n/Y/N/yes/no]"
read answer
case ${answer} in
n|N|no)
exit 0
;;
esac
fi
#获取两个文件
wget_file ${DIST_URL}${DIST_DIR} Release.gpg
wget_file ${DIST_URL}${DIST_DIR} Release
#给你看看新的Release的时间
grep Date: Release
#如果比上面一个原来的时间新,那就意味着需要更新了
#如果觉得没有必要,也可以自己放弃
echo -n "Will you refresh package list ?[y/n/Y/N/yes/no]"
read answer
case ${answer} in
Y|y|yes)
#如果要去更新,那么就去取软件列表回来,多线程
refresh_package_list
;;
esac
代码: 全选
bash sync_repo.sh
代码: 全选
apt-get install apache2
sudo /etc/init.d/apache2 start
这里我是直接编辑 /etc/hosts的,指向 127.0.0.1 如:
代码: 全选
# more /etc/hosts
127.0.0.1 localhost
127.0.0.1 archive.ubuntu.com
代码: 全选
apt-get update
第二部分:多线程 apt-get dist-upgrade , 下载软件包
说明:这里使用了网络上的 apt-axel 这个脚本,大家可以去搜索一下,并感谢一下原作者,至少在心里默念3编。
1:上面,我们修改了/etc/hosts,现在要改回去。 直接把那一行注释掉,不要删除,因为下次还要用。修改为:
代码: 全选
# more /etc/hosts
127.0.0.1 localhost
#127.0.0.1 archive.ubuntu.com
我仅仅做了略微的修改[原来的里面支持8个源],并且补充了一些注释,让新生代小白容易看一点。
apt-axel :
代码: 全选
#!/bin/bash
###########################################################################
#
# Authors: Jesús Espino García & Lucas García
# Email: jespino@imap.cc
# Date: 31/05/2004
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
###########################################################################
# If the config file not exist, load the default parameters
VERSION="0.1"
#可以在本地存在一个配置文件,没有也没有关系,我现在就没有建,脚本会自动判断的。
CONFIG_FILE="/etc/apt-axel.conf";
#注意,如下命令统统在tmp目录下面执行。
cd /tmp
#如果在本地有了配置,就加载,我现在没有这个配置,当然不加载
if [ -f $CONFIG_FILE ]; then
. $CONFIG_FILE
else
#配置都下载下面几个语句里面了。
# Verbose TRUE or FALSE
VERBOSE="FALSE"
# Conections
#默认多线程的连接数
CONNECTIONS=8
# Servers
#服务器路径,与第一部分里面那个基本一致,但是注意这里后面是有 ubuntu 这个子目录的。
server1="http://archive.ubuntu.com/ubuntu/"
fi
# Set the package variable to be global
package="";
# Show the help
#函数:显示一个帮助
mostrar_ayuda() {
echo "Usage: apt-axel <option> <package>";
echo "";
echo "Options:";
echo " install - Install new packages (paquete es libc6 y no libc6.deb)";
echo " upgrade - Do a software upgrade";
echo " dist-upgrade - Do a distribution upgrade, see apt-get(8)";
echo " --version - Print the current version of apt-axel";
echo " --help - Show this help";
echo "";
}
# Get a package from the ftp server
#函数:这个就是多线程去取软件包的。
get_package() {
#函数中的函数
descargar() {
echo "===========BEGIN DOWNLOAD ${server1}${url} ==to = /tmp/${archivo}======"
# Check the $VERBOSE variable and the filesize, if the filesize is lower than 200K will use only 4 conections
# And if the $VERBOSE variable is TRUE, then print the axel output
if [ $size -gt 200000 ]; then
echo "axel -n $CONNECTIONS $server1$url "
axel -n $CONNECTIONS $server1$url
else
echo "axel -n 4 $server1$url "
axel -n 4 $server1$url
fi
echo "===========END DOWNLOAD ${server1}${url}========"
}
# Getting data
#用apt-cache找到某个指定的软件的具体的url位置.
url=$(apt-cache show $package | grep ^Filename: | sed s/^Filename:\ //)
echo "URL:[${url}]"
#存下来的文件名称
archivo=$(echo "$url" | sed s/^.*$package/$package/)
echo "archivo:[${archivo}]"
pkgstatus=$(dpkg -s $package 2> /dev/null | grep ^Status: | grep -v "not-installed")
echo "pkgstatus:[${pkgstatus}]"
#MD5校验值,取下来以后,当然要看看包有没有损坏啦
md5sum=$(apt-cache show $package | grep ^MD5sum: | sed s/^MD5sum:\ //)
echo "md5sum:[${md5sum}]"
size=$(apt-cache show $package | grep ^Size: | sed s/^Size:\ //)
echo "size:[${size}]"
# Downloading the package
#看看之前是否已经下载过了,即本地的cache里面是否已经存在
if [ -f /var/cache/apt/archives/$archivo ]; then
echo -n "Package already downloaded. Checking md5sum of $package package: "
#如果md5不匹配,还是要删除再重新去下载
while [ $md5sum != $(md5sum /var/cache/apt/archives/$archivo | sed s/\ .*$//) ]; do
echo "incorrect"
echo "Downloading again $package package."
rm -f /var/cache/apt/archives/$archivo
descargar
done
echo "correct"
#如果本地没有cache,去下载吧,没什么可犹豫的
else
descargar
fi
# Move the file to /var/cache/apt/archives
#如果下载成功了,把文件移到cache目录下面去。
if [ -f /tmp/${archivo} ]; then
if [ $md5sum == $(md5sum /tmp/$archivo | sed s/\ .*$//) ]; then
mv -f /tmp/$archivo /var/cache/apt/archives/
fi
fi
}
#下面几个函数不说,大家一看函数名字也知道干什么的了
pkg_install() {
echo "want to install [$1]"
for package in $(apt-get -s install $1 | grep ^Inst\ | sed s/^Inst\ // | sed s/\ .*$//); do
echo "package:[${package}]"
get_package
done
apt-get -y install $1
}
upgrade() {
for package in $(apt-get -s upgrade | grep ^Inst\ | sed s/^Inst\ // | sed s/\ .*$//); do
get_package
done
apt-get -y upgrade
}
dist_upgrade() {
for package in $(apt-get -s dist-upgrade | grep ^Inst\ | sed s/^Inst\ // | sed s/\ .*$//); do
get_package
done
apt-get -y dist-upgrade
}
#
# Main program
#
if [ `id -u` != 0 ]; then
echo "You must be root to run this command."
else
case $1 in
install) pkg_install $2;;
upgrade) upgrade;;
dist-upgrade) dist_upgrade;;
(--version) echo "Current Version: $VERSION";;
(--help | -h) mostrar_ayuda;;
*) mostrar_ayuda;;
esac
fi
代码: 全选
apt-axel dist-upgrade
代码: 全选
apt-axel install your_package_name
完毕!