感谢支持
我们一直在努力

用Shell脚本实现自动化完成属于自己的微型Linux

前面我写了如何通过宿主RedHat系统通过精简和调用以及修改的方式,打造一个完全属于自己的微型LInux!见http://www.linuxidc.com/Linux/2011-08/40389.htm 


但是,很多人懒啊~~,所以我又写了写脚本,通过分步实现的方式。达到用一个脚本,完全的按照用户想要达到的目的安装一个属于自己的微型Linux。


那么下面我们来看如何实现: 


实现过程分析:


1.分区,按照用户所选的盘,将其格式化,分区


2.挂载,按照用户设定的的分区好的盘分别挂载在我们宿主机的一个目录上。方便对微型linux进行编辑。


3.对微型Linux进行写入各项配置信息


4.将微型Linux中我们需要用到的Bash等命令放进去


5.放入内核,和启动必须加载的配置文件


6.对用户的硬盘安装引导程序。 



好的~过程已经分析OK了,下面我们动手开始写吧!!!


第一步:实现自动分区!!



我们将问题分开来看,于是成了这样:


写一个脚本,实现将一个硬盘中原有分区信息全部删除,并重新将其分为三个区:
1、提示用户指定要操作的磁盘;如果此硬盘中有分区,显示分区信息,并判断此中分区是否仍然处于挂载状态;
   如果是,则显示分区和对应的挂载点;否则,则说明分区没有挂载;
2、提示用户接下来操作会破坏硬盘上的所有数据,并询问用户是否继续进行;形如:Continue(y/N)?
   如果用户选择继续,则抹除此硬盘上的所有分区信息(如果是仍处理挂载状态的分区,则需要先卸载);否则退出;
3、将此硬盘分为三个主分区:
  第一个主分区,50M,ext3文件系统
  第二个主分区,512M,ext3文件系统
  第三个主分区,256M,swap文件系统


OK,开始实现:


  1. #!/bin/bash   
  2. #: Title: All_Mini_Linux.sh   
  3. #: Synopsis:   
  4. #: DateTime: 2011-08-04 00:36:35   
  5. #: Version: 0.1   
  6. #: Author: weiyan   
  7. #: Options:    
  8. #   
  9. read -p “The target disk: “ DSK        # 提示用户选择即将分区的硬盘  
  10.   
  11. if fdisk -l $DSK | grep “^/dev” &> /dev/null ; then     #判断硬盘的分区状态。  
  12.   fdisk -l $DSK | grep “^/dev”  
  13.   PARTS=`fdisk -l $DSK | grep “^/dev” | awk ‘{print $1}’`  
  14.   
  15.   for I in $PARTS; do                  # 使用循环的方式,将硬盘上每一个分区的状态和是否挂载,挂载在哪告诉用户。  
  16.     if mount | grep “$I” &> /dev/null; then  
  17.        mount | grep “$I”  
  18.     else  
  19.       echo “$I is not mounted.”  
  20.     fi  
  21.   done  
  22. fi  
  23.   
  24. SPART() {                # 制作名为SPART的函数,这个函数的功能就是提示用户准备分区,当允许分区则开始分区!  
  25.   read -p “Warning !!!!! Next you do it will wipe your disk !!!! Continue(y/N)?” CHOICE  
  26.   case $CHOICE in  
  27.   y|Y)  
  28.   for I in $PARTS; do  
  29.     if mount | grep “$I” &> /dev/null; then  
  30.       fuser -km $I  
  31.       umount $I  
  32.     fi  
  33.   done  
  34.   
  35.   dd if=/dev/zero of=$DSK bs=512 count=1 &> /dev/null   # 将用户所选的硬盘的MBR直接擦除。让其成为空盘。  
  36.   
  37. echo ‘   
  38. n     
  39. p     
  40. 1  
  41.   
  42. +50M  
  43. n  
  44. p  
  45. 2  
  46.   
  47. +512M  
  48. n  
  49. p  
  50. 3  
  51.   
  52. +256M  
  53. t  
  54. 3  
  55. 82  
  56. w’ | fdisk $DSK &> /dev/null      # 将分区的信息传递给 fdisk,开始分区。  
  57.   
  58.   partprobe $DSK  
  59.   sleep 1           # 分区之后要用sleep命令让系统“沉睡”1秒,这样可以让分区的信息真正的同步进硬盘,而不至于格式化出错。  
  60.   
  61.   mke2fs -j ${DSK}1 &> /dev/null    # 分别格式化每一个分区并且格式化虚拟分区。  
  62.   mke2fs -j ${DSK}2 &> /dev/null  
  63.   mkswap ${DSK}3 &> /dev/null  
  64.   return 0  
  65.   ;;  
  66.   n|N)  
  67.     return 1  
  68.     ;;  
  69.   *)  
  70.     return 2  
  71.     ;;  
  72. esac  
  73. }  
  74. SPART              # 执行这个 SPART 函数。  
  75. [ $? -eq 0 ] && echo “The Disk wipe success !!!!!!!” || echo “Failure”    # 判断函数的返回值,如果是0,则提示分区成功。  

这样一来,我们就有了一个完整的分好了区,并且格式化了的硬盘了。接下来呢?


将硬盘挂载!

第二步:挂载!


那么将第二步好好的整理一下,发现它其实是不是实现了下面的功能呢?


写一个脚本,实现将上述步骤中创建的分区挂载至某目录:
1、写一个函数,接受两个参数,完成以下功能:  
   参数1为/boot分区对应的设备,传递至函数之后将其挂载至/mnt/boot;
   参数2为/分区对应的设备,传递至函数之后将其挂载至/mnt/sysroot;
   说明:上述的挂载点/mnt/boot和/mnt/sysroot如果事先不存在,需要先创建;如果事先存在,且已经被某设备挂载使用,则需要先卸载原来挂载的设备;
2、将第一个脚本中实现的分区1和分区2传递给些函数执行;


那么,目标有了,我们来实现它!


  1. function GUAZAI {                  # 创建一个名为 GUAZAI 的函数  
  2.         [ -d /mnt/boot ] ||  mkdir -p /mnt/boot    # 先判断我们要挂载的目录在不在,如果不在,则创建。  
  3.         umount /mnt/boot &> /dev/null              # 当有了目录之后,直接先卸载掉它,不管他之前有没有被挂载。(让我懒一下把-。-)  
  4.         mount $1 /mnt/boot                         # 挂载我们指定的参数1的目录,到挂载点。  
  5.         [ -d /mnt/sysroot ] || mkdir -p /mnt/boot   # 同上,判断第二个。  
  6.         umount /mnt/sysroot &> /dev/null  
  7.         mount $2 /mnt/sysroot  
  8. }  
  9.   
  10. GUAZAI ${DSK}1 ${DSK}2     #  执行这个函数,并传递给它两个需要挂载的分区参数。  

OK,挂载也挂载完了,接下来呢?



第三步:写入配置信息!



分析一下,我们要写入的配置信息:


首先要在我们的第二块分区上创建各种各样的文件夹,比如/bin /sbin /usr /root /home /tmp /etc 等等等等。


然后我们要创建/etc/inittab 这个文件


之后创建读取分区信息挂载信息的文件/etc/fstab


再然后呢?创建/etc/rc.d/rc.sysinit文件~


ok~分析得当!开始着手写入吧!


  1. #这里我们使用函数,传递参数,参数只有$1,而$1则是我们的分区2所挂载的目录/mnt/sysroot   
  2. function ROOTFS {        # 使用函数实现各项功能,方便其他用户或者其他程序的调用,多写成函数,为以后着想哟!  
  3.         if [ -d $1 ];then  
  4.           if mount | grep “$1” &> /dev/null ; then      #  判断我们的分区2是否正确的挂载了  
  5.              cd $1  
  6.              mkdir {boot,proc,sys,dev,home,root,etc/{rc.d,sysconfig,init.d},bin,sbin,lib,usr/{bin,sbin,lib,include},var/{log,run},tmp,mnt,opt,media} -pv &> /dev/null     #在这个目录里创建我们所需要用到的,各项文件夹。(麻雀虽小,五脏俱全嘛)  
  7.              chmod 1777 tmp/                
  8.   
  9. # create inittab   
  10. cat >>$1/etc/inittab<< EOF              #创建inittab 写入如下的信息  
  11. id:3:initdefault:  
  12. si::sysinit:/etc/rc.d/rc.sysinit  
  13. EOF  
  14.   
  15. # create rc.sysinit                     #创建rc.sysinit 写入如下的信息   
  16. cat >>$1/etc/rc.d/rc.sysinit<< EOF  
  17. #!/bin/bash   
  18. echo -e “\t\tWelcome to \033[031;1mLittle\033[0m Linux…”  
  19.   
  20. mount -n -o remount,rw /  
  21. mount -n -a  
  22.   
  23. /bin/bash  
  24. EOF  
  25.                 chmod +x etc/inittab               # 分别赋予他们执行的权限(你总不会想看到他们放在那却不能用吧-。-?)  
  26.                 chmod +x etc/rc.d/rc.sysinit  
  27.   
  28. # create fstab           # 创建fstab 将我们到时候要挂载的分区信息写入。这里注意,一定是“到时候”要挂载的。   
  29. cat >>$1/etc/fstab<< EOF  
  30. /dev/sda2               /            ext3    defaults  0 0  
  31. /dev/sda1               /boot        ext3    defaults  0 0  
  32. sysfs                   /sys         sysfs   defaults  0 0  
  33. proc                    /proc        proc    defaults  0 0  
  34. EOF  
  35.           else  
  36.                 read -p “Error,the $1 not mount ! Contiune(y|N)?” MOT   # 如果发现我们的分区2还没有挂上!就停止!  
  37.                 case $MOT in                    # 不过这应该是不会没挂上的,否则我们上一步岂不是白做了!?  
  38.                 y|Y)  
  39.                         ROOTFS /mnt/sysroot  ;;  
  40.                 *)  
  41.                         echo “Exit……”  
  42.                         return 5  
  43.                         ;;  
  44.                 esac  
  45.           fi  
  46.         fi  
  47. }  
  48.   
  49. ROOTFS /mnt/sysroot   # 最后,执行这个函数,传递给他一个/mnt/sysroot这���参数~~OK~  

好的!我们完成了前三步!总结一下: 


我们先按照用户选择的硬盘,将其分区,分成3块,然后都将其格式化。


之后我们把需要用到的分区挂载到我们设定的目录上去!


然后我们将分区内写入各项配置信息。 


接下来,看第二篇啦~完成后面三个步骤!!OK,加油~换个页面,我们继续!!

刚才我们已经完成了前三步的工作。我们再次对整个Shell脚本的实现方式进行一次分析:


实现过程分析:


1.分区,按照用户所选的盘,将其格式化,分区


2.挂载,按照用户设定的的分区好的盘分别挂载在我们宿主机的一个目录上。方便对微型linux进行编辑。


3.对微型Linux进行写入各项配置信息


4.将微型Linux中我们需要用到的Bash等命令放进去


5.放入内核,和启动必须加载的配置文件


6.对用户的硬盘安装引导程序。



———————————————————————————————————-


好的,刚才那算是帮助大家整理思路,算是“上集回顾”吧~接下来我们继续!将Shell脚本进行到底!


第四步:移植各种各样我们需要的命令进去:



脚本分析:


为了移植命令,我们就要先将我们宿主系统上的命令复制过去。
但是仅仅复制命令是不够的,我们还要将命令所对应的库文件复制过去。
那么,不同的命令有不同的样式,也有不同/相同的库文件。
我们就要辨别到底复制哪些库文件,复制到哪,有没有重复~
最后,我们要知道,不是仅仅复制一个命令就好,我们要循环的让用户选择到底需要什么命令。直到都复制结束~


好的,分析OK,我们按照计划着手去做吧!


  1. function COPYLIB {     # 我们依然使用函数,方便以后的调用工作。  
  2.   #copy command   
  3.   if which $1 &> /dev/null ;then             # 判断用户输入的命令是否真的是个命令,总不能我们输入1,也复制1进去吧~=。=  
  4.     AA=`which $1 | tail -1 | awk ‘{print $1}’`  
  5.     cp “$AA” $2“$AA”                      # 如果判断成功,则复制~  
  6.   else  
  7.     echo “$1 is not exist”  
  8.   fi  
  9.   
  10.   #copy lib                              #   开始复制命令对应的lib库文件   
  11.   for LIB in `ldd “$AA” | grep “/lib/” | sed ‘1,$s@^[[:space:]]/lib@aaa=> /lib@g’ | awk -F“=> “ ‘{print $2}’ | cut -d” “ -f1`;do  
  12.     LIBPATH=`echo $LIB | sed <a>‘s@\(.*\)/[^[:space:]]\{1,\}@\1@g’</a>`   # 我们用了一个for循环,来判断我们输入的命令所含的lib,并且将他们对齐,列表  
  13.     [ -d ${2}$LIBPATH ] || mkdir ${2}$LIBPATH                      # 判断我们即将复制过去的目录是否存在,万一不存在则创建  
  14.     [ ! -e $2/$LIB ] && cp -f $LIB ${2}$LIBPATH && echo “$LIB done”      # 开始复制~并提示 复制的效果~~  
  15.   done  
  16.   
  17. }  
  18. # 到这里,这个函数就结束了,下面我们准备调用。首先要知道,有两个命令是必须复制的,一个是bash ,一个是 init ,两个都是非常非常重要的命令。   
  19. echo “==========================================================”  
  20. echo -e “Please input COMMAND with \033[31mbash\033[0m and \033[31minit\033[0m !!!!!”  
  21. read -p “COMMAND you want?(Quit for ‘q’) :” CMD1          # 就是因为太重要,所以我们用上一条语句红色警示用户,必须先复制这两条。  
  22.                                                           # 然后我们制造一个循环,方便用户反复的加入各种各样的命令。   
  23. until [ $CMD1 == ‘q’ ]; do                                # 当然,不能总是输入吧,所以我们只需要按 ‘q’  
  24.   COPYLIB $CMD1 /mnt/sysroot                          # 执行函数 并且传递我们所输入的命令。  
  25.   echo -e “Please input COMMAND with \033[31mbash\033[0m and \033[31minit\033[0m !!!!!”  
  26.   read -p “Which COMMAND you want use ?(Quit for ‘q’) :” CMD1  
  27. done  


OK~这样一来,我们的小linux里也有了各种各样我们所输入的命令啦~接下来,就要往里添加内核了!
让我们的linux运行起来!!!!!

第五步:弄个内核!让我们的Linux拥有心脏!



在手动打造属于自己的linux的时候,我们已经知道,我们的内核是直接用RedHat的内核文件。
然后再修改initrd这个能在内存中虚拟出一个小linux方便加载根目录系统的文件。
之后,我们将其移植进去就好。


接下来,我们开始做吧~!


  1. function YDFQ {                    # 依然是函数-。-  
  2. TMPDIR=`mktemp -d /tmp/little.XX`       # 创建一个临时文件夹,一会儿我们要解压initrd.*.img 用哦~  
  3. cd $TMPDIR  
  4. zcat /boot/initrd-`uname -r`.img | cpio -id  &> /dev/null     ## 在临时文件夹中解压并展开我们的initrd文件,准备修改。  
  5. sed -i ‘s@^echo Scanning and configuring dmraid supported devices@#&@g’ init  
  6. sed -i ‘s@^echo Scanning logical volumes@#&@g’ init  
  7. sed -i ‘s@^lvm vgscan –ignorelockingfailure@#&@g’ init  
  8. sed -i ‘s@^echo Activating logical volumes@#&@g’ init  
  9. sed -i ‘s@^lvm vgchange -ay –ignorelockingfailure  vol0@#&@g’ init  
  10. sed -i ‘s@^resume LABEL=SWAP-sda3@#&@g’ init                            # 在init文件中注释掉我们没用的行~  
  11.   
  12. sed -i “s@\(mkrootdev.*\) /.*@\1 sda2@” init                        # 改变init文件中有用的,比如我们要判断到时候执行哪个盘。  
  13. find . | cpio -H newc -o –quiet | gzip -9 > /mnt/boot/initrd.gz    # 重新归档并压缩成initrd.gz文件~  
  14. cp /boot/vmlinuz-`uname -r` /mnt/boot/vmlinuz                     # 将我们整理好的文件复制到我们的分区中去!  
  15. }  
  16. YDFQ /mnt/sysroot    # 函数执行的开始-。- 好吧,请原谅我总是将它写在后面   


ok~我们小linux的心脏也有了~接下来,就是最后一步了!!!给硬盘一个引导,让他知道自己该如何运行!!!!

第六步:引导文件!



那么,既然需要引导,就又要提到我们伟大的 Grub了~ 它能直接给硬盘安装一个MBR进去~让其拥有boot loader~
这样一来,硬盘在开机启动之后就自己知道自己要做些什么了~~!
当然,我们的系统我们做主,所以里面要加上你自己的东西哟!!


开始动手吧!


  1. ## 这里我们要传递四个值到我们的函数中    
  2. ## $1=我们要安装对哪个硬盘安装bootloader     
  3. ## $2=我们的主分区,就是内核文件等所在的分区    
  4. ## $3=内核的名字     
  5. ## $4=initrd 的名字~   
  6. ##   
  7. function GRUB {         ## 好吧,各种各样的函数-。-  
  8. if [ `basename $2` == boot ];then         ## 判断用户输入的主分区是否是我们需要的主分区,不过这个肯定是了,因为下面我们手动指定了-。-  
  9.   grub-install –root-directory=/mnt $1  &> /dev/null    # 安装grub,到我们的分区去,这样我们就有了bootloader了!  
  10.   cat >>$2/grub/grub.conf<< EOF                     # 制定我们自己的开机方式~~  
  11. default=0  
  12. timeout=10  
  13. title Little Linux  
  14.         root (hd0,0)  
  15.         kernel /${3} ro root=/dev/sda2 quiet  
  16.         initrd /${4}  
  17. EOF  
  18.   
  19. else  
  20.   echo “It’s not boot !Exit & Please set it again !”   
  21. fi  
  22. }  
  23.   
  24. GRUB $DSK /mnt/boot vmlinuz initrd.gz      # 好吧,函数开始执行了-。-  
  25.   
  26. echo “Congratulation ! Your Mini Linux is install OK !”   # 显示庆祝信息!告诉用户我们已经安装好了!  



OK~~!!!! 一切搞定~


接下来我们就去测试把~


按照这样的写下来,我们可以说基本实现了一键安装linux,并且是你自己制定的哟!!!!!


~


嗯~


看懂了么?会了么-。-那么,自己做做吧~~

赞(0) 打赏
转载请注明出处:服务器评测 » 用Shell脚本实现自动化完成属于自己的微型Linux
分享到: 更多 (0)

听说打赏我的人,都进福布斯排行榜啦!

支付宝扫一扫打赏

微信扫一扫打赏