LinuxSir.cn,穿越时空的Linuxsir!

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

[原创]Archlive安装程序archlive-installer 完成3rd版本

[复制链接]
发表于 2009-6-28 19:52:38 | 显示全部楼层 |阅读模式
----------------2009-07-09----更新------------
选择目标分区后,使用--move选项重新挂载到$INSTALL目录下,以避免出现一些错误.
----------------2009-07-07----更新------------
改用pacman.static来安装软件包,以使在非Arch环境下也可以按照清单快速安装Arch GNU/Linux。。。

----------------2009-06-29----更新------------
目前功能:
1、全新安装

     本安装程序会根据自定义的软件清单快速安装Arch。
     如果没有指定软件清单,则自动从googlecode上下载现成的清单;
     可以自定义软件仓;
     自定义软件源镜像清单;

2、从archlive启动运行本程序可以复制安装正在运行的archlive到目标分区。


支持自定义安装分区——/  /home /var  /etc 可以分别分区;
自定义 menu.lst 。。。。
-------------------------------------------------

源码:  http://archlive.googlecode.com/hg/archlive-installer/

使用办法: 用archlive启动,下载脚本,sudo sh ./archlive-installer 按照提示安装就可以了!

欢迎大家勘误, 提出宝贵意见!


  1. #!/bin/bash
  2. # 本脚本是Carbon Jiao制作的Archlive安装程序,基于shell Xdialog的图形界面。
  3. # 目前支持两种安装方式:
  4. # 1、用archlive启动时,复制运行的archlive安装到目标分区;
  5. # 2、根据指定的软件清单来快速安装Arch GNU/Linux;
  6. # 待加强:
  7. # 1、优化、勘误;
  8. # 2、加入Arch官方安装方式(爱好者自行加入);
  9. # 3、多语言支持;
  10. #
  11. #2009-07-09 更新:选择目标分区后,采用--move挂载到$INSTALL目录下对应位置
  12. #2009-07-07 更新:如果启动前插入了U盘或者移动硬盘导致盘符错乱(sdb...)也可以正常安装.
  13. #                使用pamcan.static来安装arch软件包,以使在非Arch环境下也可以采用本安装程序根据软件清单快速安装Arch GNU/Linux。
  14. #

  15. if [ "$EUID" != "0" ]; then
  16.     echo "错误: 必须以root用户运行本制作脚本."
  17.     exit 1
  18. fi
  19. #if [ "x$(whereis Xdialog)" = "x" ]; then
  20. #        echo "错误,本安装程序须要xdialog的支持,请先安装此程序。"
  21. #        exit 1
  22. #fi

  23. Xdialog --version 2>&1 >/dev/null
  24. if [ $? -ne 0 ]; then
  25.         echo "错误,本安装程序须要xdialog的支持,请先安装此程序。"
  26.         exit 1
  27. fi

  28. if [ ! -f /usr/lib/liblinuxlive ]; then
  29.         wget http://archlive.googlecode.com/hg/mkarchlive/linux-live/archlive/liblinuxlive
  30.         . ./liblinuxlive
  31. else
  32.         . /usr/lib/liblinuxlive
  33. fi

  34. APPNAME=$(basename "${0}")

  35. NEW_INSTALL="全新安装Arch GNU/Linux(暂未支持)——按照官方安装指南一步步安装"
  36. NEW_QUICKINSTALL="全新快速安装Arch GNU/Linux(暂未支持)——利用软件清单快速自定义安装"
  37. COPY_INSTALL="复制安装Archlive——将目前运行的这个Archlive系统复制安装到目标分区"
  38. #INSTALL_LOG=/tmp/install.log_$$
  39. # 修正后可以用随机数
  40. INSTALL_LOG=/tmp/install.log

  41. # 安装分区挂载位置
  42. if [ ! -d /tmp/install ]; then mkdir -p /tmp/install; fi
  43. INSTALL=/tmp/install

  44. warnlogo="/usr/share/icons/gOS3_Icons/scalable/actions/process-stop.svg"

  45. # 没有此功能的提示
  46. function no_this_function ()
  47. {
  48.         Xdialog --title "没有此功能" --backtitle "没有此功能" --no-close \
  49.                 --icon $warnlogo \
  50.                 --yesno "目前还没有该功能,是否重新选择安装方式?" 0 0

  51.         if [ $? -eq 0 ]; then
  52.                 echo "提示: 目前没有此功能,请重新选择安装方式:"  >>${INSTALL_LOG}
  53.                 mainmenu
  54.         else
  55.                 echo "$(date +%D" "%T)        没有重新选择安装方式,选择退出安装程序" >>${INSTALL_LOG}
  56.         fi
  57. }

  58. # 选择关闭或者取消程序的提示
  59. function closed_prog ()
  60. {
  61.         echo "$(date +%D" "%T)        选择了取消,现在退出程序." >>${INSTALL_LOG}
  62.         Xdialog --title "警告!" --time-out 20 --no-cancel --no-buttons \
  63.                 --infobox "选择了取消,现在退出程序。" 5 40
  64.         exit 1
  65. }
  66. # 功能模块:错误提示
  67. function errors ()
  68. {
  69.         if [ $? -ne 0 ]; then
  70.                 Xdialog --title "$BOX_TITLE" --backtitle "$BACKTITLE" --no-close \
  71.                         --icon $warnlogo \
  72.                         --yesno "出现错误, 查看详情?" 0 0
  73.                 if [ $? -eq 0 ]; then
  74.                         Xdialog --title "$BOX_TITLE" --backtitle "错误信息:" --no-cancel \
  75.                                 --textbox ${INSTALL_LOG} 20 64
  76.                 fi
  77.                 exit 1
  78.         fi
  79. }
  80. # 准备快速安装的软件清单
  81. function prepare_softlist ()
  82. {
  83.         if [ -f /tmp/soft.list ]; then rm -f /tmp/soft.list; fi
  84.         if [ -f $(pwd)/soft.list }; then
  85.                 cp $(pwd)/soft.list /tmp/soft.list
  86.         else
  87.                 wget http://archlive.googlecode.com/files/soft.list
  88.                 cp soft.list /tmp/soft.list
  89.         fi
  90.         SOFT_LIST=/tmp/soft.list
  91.         Xdialog --stdout --title "编辑softlist" --no-close \
  92.                 --yesno "编辑预安装的软件清单?" 0 0
  93.         if [ $? -eq 0 ]; then
  94.                 Xdialog --title "编辑softlist" --fixed-font \
  95.                         --editbox $SOFT_LIST 0 0 2>$SOFT_LIST$$
  96.                 if [ $? -eq 0 ]; then
  97.                         mv -f $SOFT_LIST$$ $SOFT_LIST
  98.                 fi
  99.         fi
  100.         echo "$(date +%D" "%T)        $SOFT_LIST编辑完成!结果如下: " >>${INSTALL_LOG}
  101.         cat $SOFT_LIST >>${INSTALL_LOG}
  102.         echo "--------------- $SOFT_LIST --------------------"  >>${INSTALL_LOG}
  103. }

  104. function prepare_installer ()
  105. {
  106.         #使用pacman.static作为安装程序,可以在非Arch下快速安装Arch了
  107.         [ -f /tmp/usr/bin/pacman.static ] && PACMAN=/tmp/usr/bin/pacman.static
  108.         [ -f /usr/bin/pacman.static ] && PACMAN=/usr/bin/pacman.static
  109.         if [ "$(uname -m)" = "x86_64" ]; then
  110.                             PKGARG="http://repo.archlinux.fr/x86_64"
  111.         else        
  112.                         PKGARG="http://repo.archlinux-br.org/i686"
  113.         fi
  114.         if [ "$PACMAN" = "" ]; then
  115.                 cd /tmp
  116.                 echo "$(date +%D" "%T)        系统无pacman.static现在开始下载" >>${INSTALL_LOG}
  117.                 wget -c $PKGARG/$(links -dump $PKGARG | grep "pacman-static-" | cut -d " " -f 1) 2>&1  >>${INSTALL_LOG}
  118.                 if [ $? -gt 0 ]; then
  119.                         echo "错误: 下载失败" >>${INSTALL_LOG}
  120.                         Xdialog --title "无法下载pacman安装程序包!" --timeout 20 --no-close \
  121.                                 --infobox "无法下载pacman安装程序包!请确认网络是否正常连接,然后再使用本程序!" 0 0
  122.                 fi
  123.                 tar -xzvf pacman-static*.pkg.tar.gz 2>&1 >>${INSTALL_LOG}
  124.         fi
  125.         [ -f /tmp/usr/bin/pacman.static ] && PACMAN=/tmp/usr/bin/pacman.static
  126.         [ -f /tmp/usr/bin/repo-add ] && REPO-ADD=/tmp/usr/bin/repo-add
  127.         if [ "$PACMAN" = ""  -o "${REPO-ADD} ]; then
  128.                 echo "错误: 无法找到pacman.static程序,请确认下载的包是否完整!" >>${INSTALL_LOG}
  129.                 exit 1
  130.         fi
  131. }
  132. # 功能函数:在文件夹$1下创建软件仓$2
  133. function create_repo ()
  134. {
  135.         echo "$(date +%D" "%T)        在文件夹$1下创建软件仓$2" >>${INSTALL_LOG}
  136.         for pkgfile in $(ls $1/*.pkg.tar.gz); do
  137.                 REPO-ADD $1/$2.db.tar.gz $pkgfile  2>&1 >>${INSTALL_LOG}
  138.         done
  139. }
  140. # 功能函数:判断某一软件仓是否已经在pacman.conf中定义
  141. function is_in_pacmanconf ()
  142. {
  143.         if [ "x$(cat ${PACMANCONF} | sed -r "s/#.*//" | egrep  "\[*${REPO_NAME}\]")" = "x" ]; then echo "0"; fi
  144. }
  145. # 功能函数:将指定自定义软件仓配置加入到pacman.conf
  146. function add_customrepo2pacmanconf ()
  147. {
  148.    if [ "$(is_in_pacmanconf ${REPO_NAME} ${PACMANCONF})" = "0" ]; then
  149.         sudo sed -i "/# uncommented to enable the repo./ a\
  150.                 \ \n#本地自定义软件仓\n[${REPO_NAME}]\
  151.                 \nServer = file://${REPO_DIR} \n" ${PACMANCONF}
  152.         if [ $? -eq 0 ]; then
  153.                 echo "添加${REPO_DIR}下的软件仓${REPO_NAME}成功!" >>${INSTALL_LOG}
  154.         else
  155.                 echo "添加${REPO_DIR}下的软件仓${REPO_NAME}添加错误!请查看${PACMANCONF}!" >>${INSTALL_LOG}
  156.                 edit_pacmanconf
  157.                 add_customrepo2pacmanconf               
  158.         fi
  159.    else
  160.         echo "该软件仓已经添加到${PACMANCONF},请检查${PACMANCONF}:" >>${INSTALL_LOG}
  161.    fi
  162. }
  163. # 是否使用自定义repo,如果使用,则将软件仓配置加入到pacman.conf
  164. function use_my_repo ()
  165. {
  166.         Xdialog --title "使用自定义软件" --no-close --yesno "是否使用自己编译的软件?" 0 0
  167.         if [ $? -eq 0 ]; then
  168.                 echo "$(date +%D" "%T)        选择了使用自定义软件仓" >>${INSTALL_LOG}
  169.                 REPO_DIR=$(Xdialog --stdout --title "请选择自定义软件存放的文件夹" --dselect /mnt 0 0)
  170.                 REPO_NAME=$(Xdialog --stdout --title "安装GRUB的位置" --inputbox "输入自定义软件仓的名(方便以后使用):" 0 0 "archlive")
  171.                 create_repo ${REPO_DIR} ${REPO_NAME}
  172.         fi       
  173.         add_customrepo2pacmanconf       
  174. }
  175. # 编辑pacman.conf 及软件源清单文件
  176. function edit_pacmanconf ()
  177. {
  178.         Xdialog --stdout --title "编辑Arch源清单" --no-close \
  179.                 --yesno "编辑Arch源清单mirrorlist?" 0 0
  180.         if [ $? -eq 0 ]; then
  181.                 cp /etc/pacman.d/mirrorlist /tmp/mirrorlist
  182.                 MIRROR_LIST=/tmp/mirrorlist
  183.                 Xdialog --title "编辑Arch源清单mirrorlist" --fixed-font \
  184.                         --editbox $MIRROR_LIST 0 0 2>$MIRROR_LIST$$
  185.                 if [ $? -eq 0 ]; then
  186.                         mv -f $MIRROR_LIST$$ $MIRROR_LIST
  187.                         sed -i "s#Include = /etc/pacman.d/mirrorlist#Include = /tmp/mirrorlist#g" $PACMANCONF
  188.                 fi
  189.         fi

  190.         Xdialog --stdout --title "编辑pacman.conf" --no-close \
  191.                 --yesno "编辑Arch软件仓配置文件pacman.conf?" 0 0
  192.         if [ $? -eq 0 ]; then
  193.                 Xdialog --title "编辑pacman.conf" --fixed-font \
  194.                         --editbox $PACMANCONF 0 0 2>$PACMANCONF$$
  195.                 if [ $? -eq 0 ]; then
  196.                         mv -f $PACMANCONF$$ $PACMANCONF
  197.                 fi
  198.         fi
  199.         echo "$(date +%D" "%T)        $PACMANCONF编辑完成!结果如下: " >>${INSTALL_LOG}
  200.         cat $PACMANCONF >>${INSTALL_LOG}
  201.         echo "--------------- $PACMANCONF --------------------"  >>${INSTALL_LOG}
  202. }
  203. # 功能模块:准备pacman.conf文件
  204. function prepare_pacmanconf ()
  205. {
  206.         if [ -f /tmp/pacman.conf ]; then rm -f /tmp/pacman.conf; fi
  207.         if [ -f $(pwd)/pacman.conf }; then
  208.                 cp $(pwd)/pacman.conf /tmp/pacman.conf
  209.         else
  210.                 cp /etc/pacman.conf /tmp/pacman.conf
  211.         fi
  212.         PACMANCONF=/tmp/pacman.conf
  213.         use_my_repo
  214.         edit_pacmanconf
  215. }
  216. # 功能模块:自定义软件包存储位置
  217. function prepare_cache ()
  218. {
  219.         Xdialog --title "软件包缓存位置" --no-close \
  220.                 --yesno "是否另外指定Arch软件包缓存位置?\n——如果以前安装Arch时保存过软件包,\n选择该文件夹,可以加快安装速度。" 0 0
  221.         if [ $? -eq 0 ]; then
  222.                 CACHE=$(Xdialog --stdout --title "请选择软件存放位置" --dselect /mnt/ 0 0)

  223.                 # 将目标系统的/var/cache/pacman/pkg指向刚刚指定的软件包存储位置
  224.                 if [ ! -d ${INSTALL}/var/cache/pacman ]; then mkdir -p ${INSTALL}/var/cache/pacman; fi
  225.                 PWD=$(pwd)
  226.                 cd ${INSTALL}/var/cache/pacman
  227.                 if [ -d ${INSTALL}/var/cache/pacman/pkg ]; then rm -rf ${INSTALL}/var/cache/pacman/pkg; fi
  228.                 ln -sfv $CACHE ./pkg
  229.                 cd $PWD
  230.         else
  231.                 CACHE=${INSTALL}/var/cache/pacman/pkg
  232.                 if [ ! -d $CACHE ]; then mkdir -p $CACHE; fi
  233.         fi
  234. }
  235. # 功能模块:根据指定的软件清单,根据自定义的pacman.conf及自定义软件仓安装软件到目标文件夹
  236. function install_per_list ()
  237. {
  238.         mkdir -p "${INSTALL}/var/lib/pacman"       
  239.         mkdir -p "${INSTALL}/dev"
  240.         mknod -m 660 ${INSTALL}/dev/console c 5 1 >/dev/null
  241.         mknod -m 660 ${INSTALL}/dev/null c 1 3 >/dev/null
  242.         mknod -m 660 ${INSTALL}/dev/zero c 1 5 >/dev/null

  243.         [ -e "${INSTALL}/var/lib/pacman/db.lck" ] && (rm -f ${INSTALL}/var/lib/pacman/db.lck)

  244.         echo "$(date +%D" "%T)        开始安装程序,先更新软件仓库信息:" >>${INSTALL_LOG}
  245.         $PACMAN -Sy --noconfirm --config "${PACMANCONF}" --cachedir "${CACHE}" -fr "${INSTALL}" 2>&1 >>${INSTALL_LOG}
  246.         cat  "$SOFT_LIST" | grep -v "^#" | while read pkgname; do
  247.                 echo "$(date +%D" "%T)        安装 $pkgname" >>${INSTALL_LOG}
  248.                 $PACMAN -S -f --needed --noconfirm --config "${PACMANCONF}" --cachedir "$CACHE" \
  249.                         -r "${INSTALL}" $pkgname 2>&1 >>${INSTALL_LOG}
  250.         done
  251.         echo "$(date +%D" "%T)        软件包安装完成!" >>${INSTALL_LOG}
  252. }
  253. # 功能模块:挂载所有分区
  254. function mount_all_partitions ()
  255. {
  256.         echo "$(date +%D" "%T)        挂载还没有挂载的分区" >>${INSTALL_LOG}
  257.         #Xdialog --title "挂载分区" --timeout 20 --no-close \
  258.         #        --progress "挂载还没有挂载的分区到/mnt下,请稍候" 0 0
  259.         # 想做个进度条,不太清除progress对应用法, 帮助不够全
  260.         #
  261.         Xdialog --title "挂载分区!" --timeout 20 --no-close \
  262.                 --infobox "挂载还没有挂载的分区到/mnt下,请稍候!" 0 0
  263.         local FSTAB FSTABTMP
  264.         FSTAB="/etc/fstab"
  265.         if [ -f $FSTAB ]; then rm -f $FSTAB; fi
  266.         list_partition_devices | while read DEVICE; do
  267.                 MNT=$(device_mountdir $DEVICE)
  268.                 FS=$(device_filesystem $DEVICE)
  269.                 OPT=$(fs_options $FS fstab)
  270.                 if [ "$FS" = "swap" ]; then
  271.                         fstab_add_line $FSTAB $DEVICE $MNT $FS $OPT
  272.                 fi
  273.                 if is_supported_filesystem "$FS"; then
  274.                         if [ "x$OPT" != "x" ]; then
  275.                                 if [ ! -d /mnt/live/mnt/$(basename $DEVICE) ] || [ "x$(ls /mnt/live/mnt/$(basename $DEVICE))" = "x" ]; then
  276.                                         fstab_add_line $FSTAB $DEVICE $MNT $FS $OPT
  277.                                         if [ ! -d /$MNT ]; then mkdir -p "/$MNT"; fi
  278.                                 fi
  279.                         fi
  280.                 fi
  281.            done
  282.         umount -a > /dev/null 2>&1
  283.         mount -a > /dev/null 2>&1
  284.         if [ $? -eq 0 ]; then
  285.                 Xdialog --title "挂载分区完成!" --timeout 20 --no-close \
  286.                         --infobox "挂载分区完成,现在进行下一步" 0 0
  287.                 echo "$(date +%D" "%T)        挂载分区完成!" >>${INSTALL_LOG}
  288.         else
  289.                 Xdialog --title "挂载部分分区失败" --timeout 50 --no-close \
  290.                         --icon $warnlogo \
  291.                         --infobox "请确认是否所有分区格式被目前系统所支持,!\n请更新系统后再运行本安装程序!" 0 0
  292.                 echo "$(date +%D" "%T)        挂载部分分区失败,请确认是否所有分区被目前系统所支持!\n\
  293.                         请更新系统后再运行本安装程序!" >>${INSTALL_LOG}
  294.                 exit 1
  295.         fi
  296. }
  297. # 功能函数:选择分区并判断选择的分区是否符合要求
  298. function select_partition ()
  299. {
  300.         while true; do
  301.                 partition=$(Xdialog --stdout --title "请选择$1分区" --dselect /mnt 0 0)
  302.                 if [ $? -ne 0 ]; then
  303.                         closed_prog
  304.                         break
  305.                 else
  306.                         if [ "x$(blkid | cut -d ":" -f 1 | grep "$(basename $partition)")" != "x" ] &&\
  307.                                 [ ! -d /mnt/live$partition ] || [ "x$(ls /mnt/live$partition)" = "x" ]; then
  308.                                         echo $partition
  309.                                         break
  310.                         else
  311.                                 Xdialog --title "!" --time-out 20 --no-cancel --no-buttons \
  312.                                         --infobox "错误!选择的分区无法作为安装的目标分区,\n请重新选择目标分区!" 5 40
  313.                         fi
  314.                 fi
  315.         done       
  316. }
  317. # 功能模块:选择安装的目标分区,/  /home /var /etc
  318. function select_target_partitions ()
  319. {
  320.         Xdialog --title "选择安装的目标分区" --timeout 30 --no-close \
  321.                 --infobox "选择安装的目标分区, 可以将 / /home /var /etc 独立分区,\n\
  322.                 如果所有的安装到一个分区,则选择分区位置时候选择根分区的位置即可。 " 0 0
  323.         echo "$(date +%D" "%T)        ***现在选择安装的目标分区:" >>${INSTALL_LOG}
  324.         target_root=$(select_partition root)
  325.         echo "$(date +%D" "%T)        选择的目标系统root分区为${target_root}" >>${INSTALL_LOG}
  326.         target_boot=$(select_partition /boot)
  327.         echo "$(date +%D" "%T)        选择的目标系统/boot分区为${target_boot}" >>${INSTALL_LOG}
  328.         target_home=$(select_partition /home)
  329.         echo "$(date +%D" "%T)        选择的目标系统/home分区为${target_home}" >>${INSTALL_LOG}
  330.         target_var=$(select_partition /var)
  331.         echo "$(date +%D" "%T)        选择的目标系统/var分区为${target_var}" >>${INSTALL_LOG}
  332.         target_etc=$(select_partition /etc)
  333.         echo "$(date +%D" "%T)        选择的目标系统/etc分区为${target_etc}" >>${INSTALL_LOG}
  334. }
  335. # 功能模块:是否已经准备好分区,如果没有则调用gparted分区
  336. function prepare_partitions ()
  337. {
  338.         Xdialog --title "准备分区" --yesno "\n是否已经准备好安装的目标分区?\n如果还没有分区或者没有将目标分区格式化为需要的文件系统\n\
  339.                                                 则选NO调用Gparted进行分区、格式化" 0 0
  340.         if [ $? -ne 0 ]; then
  341.                 echo "$(date +%D" "%T)        选择调用分区软件Gparted进行分区" >>${INSTALL_LOG}
  342.                 gparted >>${INSTALL_LOG}  2>&1
  343.                 echo "$(date +%D" "%T)        Gparted分区完成" >>${INSTALL_LOG}
  344.         fi
  345. }

  346. # 功能函数:文件夹拷贝
  347. # $1 需要复制的目录
  348. # ${INSTALL}安装的目标分区挂载的目录,例如/tmp/install
  349. function copydir ()
  350. {
  351.         d=$( dirname $1 )
  352.         if [ "${d}" == "/" ]; then
  353.                 cp -af $1 ${INSTALL}
  354.                 echo "$(date +%D" "%T)        复制$1到${INSTALL}" >>${INSTALL_LOG}
  355.         else
  356.                 mkdir -p ${INSTALL}${d}
  357.                 cp -af $1 ${INSTALL}${d}
  358.                 echo "$(date +%D" "%T)        复制$1到${INSTALL}${d}" >>${INSTALL_LOG}
  359.         fi
  360. }
  361. # 功能函数,挂载分区到指定目录
  362. function mount_target_partition ()
  363. {
  364.         #umount -l /dev/$(basename $1)
  365.         #mount /dev/$(basename $1) $INSTALL/${2}
  366.         mount --move $1 $INSTALL/${2}
  367.         echo "$(date +%D" "%T)        挂载目标${targetpartition#target_}分区$1到$INSTALL/${2}" >>${INSTALL_LOG}
  368. }
  369. # 功能模块: 重新挂载目标分区
  370. function remount_target_partitions ()
  371. {
  372.         echo "$(date +%D" "%T)        挂载相应分区到$INSTALL" >>${INSTALL_LOG}

  373.         mkdir -p $INSTALL/{boot,home,var,etc}

  374.         # 这步花了些时间,不过最后查到bash的新的变量间接引用功能才得以优化!
  375.         for targetpartition in target_root target_boot target_var target_home target_etc; do
  376.                 if [ "$targetpartition" = "target_root" ]; then
  377.                         mount_target_partition ${!targetpartition} ""
  378.                 else
  379.                         if [ "${!targetpartition}" != "${target_root}" ]; then
  380.                                 mount_target_partition ${!targetpartition} ${targetpartition#target_}
  381.                         fi
  382.                 fi
  383.         done

  384.         echo "$(date +%D" "%T)        创建pacman需要的目录" >>${INSTALL_LOG}
  385.         ! [ -d $INSTALL/var/lib/pacman ] && mkdir -p $INSTALL/var/lib/pacman
  386.         ! [ -d /var/lib/pacman ] && mkdir -p /var/lib/pacman
  387.         echo "$(date +%D" "%T)        挂载proc sys dev以使mkinitcpio正常工作" >>${INSTALL_LOG}
  388.         ! [ -d $INSTALL/proc ] && mkdir $INSTALL/proc
  389.         ! [ -d $INSTALL/sys ] && mkdir $INSTALL/sys
  390.         ! [ -d $INSTALL/dev ] && mkdir $INSTALL/dev
  391.         mount -t proc none $INSTALL/proc
  392.         mount -t sysfs none $INSTALL/sys
  393.         mount -o bind /dev $INSTALL/dev
  394. }
  395. # 功能模块:复制安装
  396. function copyall ()
  397. {
  398.         echo "$(date +%D" "%T)        复制文件到$INSTALL" >>${INSTALL_LOG}
  399.         Xdialog --title "复制文件" --time-out 20 --no-cancel --no-buttons \
  400.                 --infobox "正在复制文件到目标分区" 5 40

  401.         for dir in /boot /usr /home /bin /etc /root /sbin /srv /lib /opt /home /var; do
  402.                 copydir $dir
  403.         done       
  404. }
  405. # 功能模块:提示安装成功
  406. function finished_installation ()
  407. {
  408.         Xdialog --title "恭喜,安装完成!" --time-out 10 --no-cancel --no-buttons \
  409.                 --infobox "恭喜, 安装完成!如果要看安装日志\n请直接打开文件${INSTALL_LOG}" 5 40
  410.         echo "$(date +%D" "%T)        安装完成,自动退出安装程序! " >>${INSTALL_LOG}
  411. }


  412. # 功能函数:获取指定设备的UUID
  413. # $1 设备名   比如/dev/sda1
  414. # 如果获取成功则返回设备的UUID,否则返回空
  415. getuuid()
  416. {
  417.     if [ "${1%%/[hs]d?[0-9]}" != "${1}" ]; then
  418.         echo "$(blkid -s UUID -o value ${1})"
  419.     fi
  420. }
  421. # 功能函数:更新fstab条目
  422. function add_fstab ()
  423. {
  424.         if [ "$uuid" = "n" ]; then $DEVICE=/dev/$(basename $1); else $DEVICE=$(getuuid /dev/$(basename $1)); fi
  425.         MNT=$(device_mountdir /dev/$(basename $1))
  426.         FS=$(device_filesystem /dev/$(basename $1))
  427.         OPT=$(fs_options $FS fstab)
  428.         if [ "x$OPT" != "x" ]; then fstab_add_line $FSTAB $DEVICE $MNT $FS $OPT; fi
  429. }
  430. # 功能模块: 更新fstab
  431. function update_target_fstab ()
  432. {
  433.         useuuid=$(Xdialog --stdout --screen-center --backtitle "选择fstab中设备描述方式" --title "fstab中设备描述用UUID还是设备名比如/dev/sda1" \
  434.                 --radiolist "Select methods in fstab:" 15 80 0 \
  435.                 "1" "使用UUID"  off \
  436.                 "2" "直接使用设备名"  ON)
  437.         if [ "$useuuid" = 1 ]; then uuid="y"; else uuid="n"; fi

  438.         mkdir $INSTALL/mnt
  439.         if [ -f $INSTALL/etc/fstab ]; then rm -f $INSTALL/etc/fstab; fi

  440.         echo "####  以下内容为Archlive installer自动添加 ####" >$INSTALL/etc/fstab
  441.         FSTAB="$INSTALL/etc/fstab"

  442.         for targetpartition in target_root target_boot target_var target_home target_etc; do
  443.                 if [ "$targetpartition" = "target_root" ]; then
  444.                         add_fstab ${!targetpartition} ""
  445.                 else
  446.                         if [ "${!targetpartition}" != "${target_root}" ]; then
  447.                                 add_fstab ${!targetpartition}
  448.                         fi
  449.                 fi
  450.         done

  451.         list_cdrom_devices | while read DEVICE; do
  452.                 MNT=$(device_mountdir $DEVICE)
  453.                 FS=$(device_filesystem $DEVICE)
  454.                 if [ "$FS" = "" ]; then FS=iso9660; fi
  455.                 fstab_add_line $FSTAB "#$DEVICE" $MNT $FS $(fs_options $FS fstab)
  456.         done

  457.         list_partition_devices | while read DEVICE; do
  458.                 MNT=$(device_mountdir $DEVICE)
  459.                 FS=$(device_filesystem $DEVICE)
  460.                 OPT=$(fs_options $FS fstab)

  461.                 if [ "$FS" = "swap" ]; then fstab_add_line $FSTAB $DEVICE $MNT $FS $OPT; fi

  462.                 # If the partition has a valid filesystem, add it to fstab
  463.                 if is_supported_filesystem "$FS"; then
  464.                         if [ "x$OPT" != "x" ]; then fstab_add_line $FSTAB $DEVICE $MNT $FS $OPT; fi
  465.                 fi
  466.         done

  467.         fstab_add_line $FSTAB none /proc proc defaults
  468.         fstab_add_line $FSTAB none /sys sysfs defaults
  469.         fstab_add_line $FSTAB none /dev/pts devpts gid=5,mode=620
  470.         fstab_add_line $FSTAB tmpfs /dev/shm tmpfs defaults
  471.         fstab_add_line $FSTAB tmpfs /tmp tmpfs defaults
  472.         fstab_add_line $FSTAB tmpfs /tmp tmpfs defaults,mode=1777
  473.         fstab_add_line $FSTAB tmpfs /var/tmp tmpfs defaults,mode=1777
  474.         fstab_add_line $FSTAB tmpfs /var/log tmpfs defaults,mode=0755,size=1M
  475.         echo "$(date +%D" "%T)        修正目标系统fstab中的盘符sdb sdc到sda(如果启动前出入了U盘启动可能就需要修正)" >>${INSTALL_LOG}
  476.         sed -i "s%sd[b-z]%sda%g" $FSTAB
  477.        
  478.         Xdialog --title "编辑、查看目标系统的fstab" --fixed-font \
  479.                 --editbox $FSTAB 0 0 2>$FSTAB$$
  480.         if [ $? -eq 0 ]; then mv -f $FSTAB$$ $FSTAB; fi
  481.         echo "$(date +%D" "%T)        目标系统fstab更新完成!结果如下: " >>${INSTALL_LOG}
  482.         cat $FSTAB >>${INSTALL_LOG}
  483.         echo "-------- fstab --------------------"  >>${INSTALL_LOG}
  484. }

  485. # 功能模块:创建启动内核镜像
  486. function mkinitrdimg ()
  487. {
  488.         idir=${INSTALL}/etc/mkinitcpio.d
  489.         presets=$( ls ${idir} | grep "^kernel.*\.preset$" )

  490.         echo "将mkinitcpio.conf中的ide替换为pata" >>${INSTALL_LOG}
  491.         if egrep "^HOOKS=.* pata" ${INSTALL}/etc/mkinitcpio.conf &>/dev/null; then
  492.                 rplc=""
  493.         else
  494.                 rplc=" pata"
  495.         fi
  496.         sed -i "s|\(^HOOKS=.*\) ide|\1${rplc}|" ${INSTALL}/etc/mkinitcpio.conf 2>&1 >>${INSTALL_LOG}

  497.         echo "$(date +%D" "%T)        重新以 --bind 方式挂载proc sys dev以使mkinitcpio正常工作:" >>${INSTALL_LOG}
  498.         mount --bind /proc ${INSTALL}/proc 2>&1 >>${INSTALL_LOG}
  499.         mount --bind /sys ${INSTALL}/sys 2>&1 >>${INSTALL_LOG}
  500.         mount --bind /dev ${INSTALL}/dev 2>&1 >>${INSTALL_LOG}

  501.         echo "$(date +%D" "%T)        开始创建目标系统的启动内核镜像: " >>${INSTALL_LOG}
  502.         cat /proc/mounts | grep ${INSTALL} | sed "s|${INSTALL}|/|" | \
  503.         sed "s|//|/|" >${INSTALL}/etc/mtab 2>&1 >>${INSTALL_LOG}

  504.         #创建启动内核镜像
  505.             chroot ${INSTALL} /sbin/mkinitcpio -p ${presets%.preset} 2>&1 >>${INSTALL_LOG}

  506.         :>${INSTALL}/etc/mtab
  507.         umount ${INSTALL}/dev
  508.         umount ${INSTALL}/sys
  509.         umount ${INSTALL}/proc

  510.         Xdialog --title "启动内核镜像创建完成!" --time-out 10 --no-cancel --no-buttons \
  511.                 --infobox "启动内核镜像创建完成,现在进行下一步。" 5 40
  512.         echo "$(date +%D" "%T)        启动内核镜像创建完成。" >>${INSTALL_LOG}
  513. }

  514. #功能函数:初始化menu.lst
  515. function init_menu_list ()
  516. {       
  517.         menulist=${INSTALL}/boot/grub/menu.lst
  518.         echo "$(date +%D" "%T)        初始化$menulist文件" >>${INSTALL_LOG}
  519.         if [ -f $menulist ]; then rm -f $menulist; fi
  520.         echo "######      menu.lst由archlive-installer于$(date +%D" "%T)初始化      ######" > $menulist
  521.         echo "timeout 300" >> $menulist
  522.         echo "default 0" >>$menulist
  523.         echo "" >>$menulist

  524.         kernels=( $( ls ${INSTALL}/boot/vmlinuz* 2>/dev/null ) )
  525.         if [ ${#kernels[@]} -ne 1 ]; then
  526.                 echo "                警告:在${INSTALL}/boot/下发现两个内核文件。"  >>${INSTALL_LOG}
  527.                 Xdialog --title "警告!" --time-out 20 --no-cancel --no-buttons \
  528.                         --infobox "警告:在${INSTALL}/boot/下发现两个内核文件,\n请选择一个内核作为启动内核。" 5 40
  529.                 kernel=$(Xdialog --stdout --title "请选择一个内核文件(vmlinuz或者vmlinuz26作为启动内核" \
  530.                                 --fselect "${INSTALL}/boot/vmlinuz26" 0 0)
  531.                 echo "$(date +%D" "%T)        选择了$kernel作为最终的启动内核。" >>${INSTALL_LOG}
  532.                 boot_kernel=$(basename ${kernel})
  533.         else
  534.                 boot_kernel=$(basename ${kernels})
  535.         fi

  536.         presets=$(ls ${INSTALL}/etc/mkinitcpio.d | grep "^kernel.*\.preset$" )
  537.         source ${INSTALL}/etc/mkinitcpio.d/$presets
  538.         imgname=$(basename ${default_image})
  539.         fallbackimgname=$(basename ${fallback_image})

  540.         bootindex=${target_boot#/dev/sd[a-z]}
  541.         let bootindex-=1
  542.         if [ "${target_boot}" != "${target_root}" ]; then bootdir=""; else bootdir="/boot"; fi

  543.         echo "title  Arch Linux (Installed by Archlive-installer)" >>$menulist
  544.         echo "root (hd0,$bootindex)" >>$menulist
  545.         echo "kernel $bootdir/${boot_kernel} root=/dev/sda${target_root#/dev/sd[a-z]} ro vga=791" >>$menulist
  546.         echo "initrd $bootdir/$imgname" >>$menulist

  547.         echo "" >>$menulist
  548.         echo "title  Arch Linux (Safemode, Installed by Archlive-installer)" >>$menulist
  549.         echo "root (hd0,$bootindex)" >>$menulist
  550.         echo "kernel $bootdir/${boot_kernel} root=/dev/sda${target_root#/dev/sd[a-z]} ro vga=791" >>$menulist
  551.         echo "initrd $bootdir/$fallbackimgname" >>$menulist
  552.         echo "" >>$menulist

  553.         if [ -f /mnt/sd[a-z]1/ntldr ]; then
  554.                 echo "                 ---> 发现/dev/sda1下安装有Windows系统(WinXp Win 2003...)" >>${INSTALL_LOG}
  555.                 echo "title MS Windwos OS" >>$menulist
  556.                 echo "rootnoverify (hd0,0)" >>$menulist
  557.                 echo "makeactive" >>$menulist
  558.                 echo "chainloader  +1" >>$menulist
  559.         fi
  560.         echo "######      List above was created by Archlive-installer      ######" >>$menulist

  561.         echo "$(date +%D" "%T)        初始化$menulist文件完成,内容如下:" >>${INSTALL_LOG}
  562.         cat $menulist >>${INSTALL_LOG}
  563. }
  564. # 功能函数:安装grub
  565. function installgrub ()
  566. {
  567.         echo "$(date +%D" "%T)        开始安装GRUB到$1:" >>${INSTALL_LOG}
  568.         mount --bind /proc ${INSTALL}/proc
  569.         mount --bind /sys ${INSTALL}/sys
  570.         mount --bind /dev ${INSTALL}/dev
  571.         cat /proc/mounts | grep ${INSTALL} | sed "s|${INSTALL}|/|" | \
  572.                     sed "s|//|/|" >${INSTALL}/etc/mtab
  573.         chroot ${INSTALL} /sbin/grub-install --no-floppy $1 2>&1 >>${INSTALL_LOG}
  574.         : >${INSTALL}/etc/mtab
  575.         umount ${INSTALL}/dev
  576.         umount ${INSTALL}/sys
  577.         umount ${INSTALL}/proc
  578.         echo "$(date +%D" "%T)        安装GRUB到$1完成。" >>${INSTALL_LOG}
  579.         Xdialog --title "GRUB已经成功安装" --time-out 20 --no-cancel --no-buttons \
  580.                 --infobox "GRUB已经成功安装到$1,现在进行下一步。" 5 40
  581. }

  582. #功能模块: 安装配置bootloader
  583. function prepare_bootloader ()
  584. {
  585.         # 以下步骤非必须,但为了有人自己编辑菜单,就先复制相关文件,避免安装grub出错.
  586.         if [ ! -d ${INSTALL}/boot/grub ]; then
  587.                 mkdir -p ${INSTALL}/boot/grub
  588.                 cp -af ${INSTALL}/usr/lib/grub/i386-pc/* ${INSTALL}/boot/grub/
  589.         fi
  590.         # 初始化menu.lst
  591.         init_menu_list

  592.         Xdialog --title "是否安装GRUB?" --no-close --yesno "是否安装GRUB?" 0 0       
  593.         if [ $? -eq 0 ]; then
  594.                 location=$(Xdialog --stdout --title "安装GRUB的位置" --inputbox "输入安装GRUB的位置\n(如果启动前已经插入U盘,实际硬盘盘符可能是/dev/sdb或者/dev/sdc...请小心输入):" 0 0 "/dev/sda")
  595.                 installgrub $location
  596.         fi

  597.         Xdialog --stdout --title "编辑menu.lst?" --no-close \
  598.                 --yesno "编辑GRUB的启动菜单配置文件menu.lst?" 0 0
  599.         if [ $? -eq 0 ]; then
  600.                 menulist=$(Xdialog --stdout --title "选择预编辑的Menu.lst" --fselect "${INSTALL}/boot/grub/menu.lst" 0 0)
  601.                 Xdialog --title "编辑menu.lst" --fixed-font \
  602.                         --editbox $menulist 0 0 2>$menulist$$
  603.                 if [ $? -eq 0 ]; then
  604.                         mv -f $menulist$$ $menulist
  605.                         echo "$(date +%D" "%T)        menu.lst编辑完成!结果如下: " >>${INSTALL_LOG}
  606.                         cat $menulist >>${INSTALL_LOG}
  607.                         echo "--------------- $menulist --------------------"  >>${INSTALL_LOG}
  608.                 fi
  609.         fi       
  610. }
  611. function newinstall ()
  612. {
  613.         echo "$(date +%D" "%T)----${NEW_INSTALL}----开始----" >>${INSTALL_LOG}
  614.         no_this_function
  615.         #finished_installation
  616. }

  617. function newquickinstall ()
  618. {
  619.         echo "$(date +%D" "%T)----${NEW_QUICKINSTALL}----开始----" >>${INSTALL_LOG}
  620.         prepare_partitions                #分区
  621.         mount_all_partitions                #挂载分区以选择目标分区,挂载于/mnt下
  622.         select_target_partitions         #选择目标安装分区
  623.         remount_target_partitions        #重新挂载目标安装分区到$INSTALL下

  624.         prepare_installer                                #准备安装程序
  625.         prepare_pacmanconf                #准备pacman.conf文件,是否自定义repo,是否自定义mirrorlist
  626.         prepare_cache                        #自定义安装过程中下载的软件包存储位置
  627.         prepare_softlist                        #自定义预安装的软件清单
  628.         install_per_list                        #按照定义的软件清单安装到目标分区
  629.         update_target_fstab                #更新目标系统的fstab文件
  630.         prepare_bootloader                #编辑menu.lst,安装grub
  631.         finished_installation                #完成安装的提示
  632. }

  633. function copyinstall ()
  634. {
  635.         echo "$(date +%D" "%T)----${COPY_INSTALL}----开始----" >>${INSTALL_LOG}
  636.         prepare_partitions                #分区
  637.         mount_all_partitions                #挂载分区以选择目标分区,挂载于/mnt下
  638.         select_target_partitions                #选择目标安装分区
  639.         remount_target_partitions        #重新挂载目标安装分区到$INSTALL下
  640.         copyall                                #将archlive的各个目录复制到目标系统
  641.         update_target_fstab                #更新目标系统的fstab文件
  642.         mkinitrdimg                        #创建目标系统的内核镜像文件
  643.         prepare_bootloader                #编辑menu.lst,安装grub
  644.         finished_installation                #完成安装的提示
  645. }
  646. ############################
  647. # 主程序
  648. ###########################
  649. function mainmenu ()
  650. {
  651.         selection=$(Xdialog --stdout --screen-center --backtitle "Archlive 安装程序 " --title "选择安装方式" \
  652.                 --radiolist "请在如下列表中选择安装方式(安装日志文件保存于${INSTALL_LOG}):" 15 80 0 \
  653.                 "1" "${NEW_INSTALL}"  off \
  654.                 "2" "${NEW_QUICKINSTALL}"  off \
  655.                 "3" "${COPY_INSTALL}" ON)
  656.         case $? in
  657.           0)
  658.                 #选择安装方式程序正常执行
  659.                 if [ ! -f ${INSTALL_LOG} ]; then touce ${INSTALL_LOG}; fi
  660.                 if [ "x$(grep "重新选择安装方式" ${INSTALL_LOG})" != "x" -a "x$(grep "安装完成" ${INSTALL_LOG})" = "x" ]; then
  661.                         echo "-->$(date +%D" "%T)        选择了安装方式$selection" >>${INSTALL_LOG}
  662.                 else
  663.                         echo "$(date +%D" "%T)        选择了安装方式$selection" >${INSTALL_LOG}
  664.                 fi
  665.                 case $selection in
  666.                         1) newinstall ;;
  667.                         2) newquickinstall ;;
  668.                         3) copyinstall ;;
  669.                 esac
  670.                 ;;
  671.           1)
  672.                    echo "$(date +%D" "%T)        选择了取消退出程序." >>${INSTALL_LOG} ;;
  673.           255)
  674.                    echo "$(date +%D" "%T)        关闭程序." >>${INSTALL_LOG} ;;
  675.         esac
  676. }
  677. mainmenu
复制代码
发表于 2009-6-28 21:43:05 | 显示全部楼层
支持一下~~~
回复 支持 反对

使用道具 举报

发表于 2009-6-29 00:23:23 | 显示全部楼层
围观一下~~~
回复 支持 反对

使用道具 举报

发表于 2009-6-29 01:45:16 | 显示全部楼层
惨无人道的围观
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-6-29 18:59:34 | 显示全部楼层
2009-06-29 更新: 加入了全新安装功能,目前应用性更广了。。。

欢迎大家提出宝贵意见。。。
回复 支持 反对

使用道具 举报

发表于 2009-6-29 19:13:47 | 显示全部楼层
Post by jarryson;2001930
惨无人道的围观

好好的帖子就这样被水了………………
回复 支持 反对

使用道具 举报

发表于 2009-7-1 10:08:02 | 显示全部楼层
carbon兄老这样骗精华不厚道了哈!

呵呵
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-1 18:44:59 | 显示全部楼层
Post by athurg;2002562
carbon兄老这样骗精华不厚道了哈!

呵呵


咋就成了骗阿。。。!
名副其实的自主知识产权阿。。。!哈
回复 支持 反对

使用道具 举报

发表于 2009-7-3 07:19:56 | 显示全部楼层
up,像楼主这样有创新与奉献的人不多啦。
大家都喜欢聊聊天,不大做实事的。
script收下了,测试测试。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2009-7-7 14:59:10 | 显示全部楼层
今日重要更新:
修补前一版本的bug——系统启动时已经插入U盘或者移动硬盘导致盘符非/dev/sda的时候无法正确确定menu.lst fstab设备名的问
题。同时加入Xdialog程序是否在系统存在的判断。

新加入功能: 在非Arch环境下,也可以利用该脚本根据软件清单快速定制安装Arch GNU/Linux。。。

http://archlive.googlecode.com/files/archlive-installer
回复 支持 反对

使用道具 举报

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

本版积分规则

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