打造自己的专属Linux(二):使用脚本实现自动化建立小Linux与命令移植

这是我前几天在马哥的带领下写的6个脚本,他们串起来就可以实现(一)篇一所有的功能,很方便吧微笑我们以后要通过不断倒腾这个小linux,来由浅入深的学习linux的系统构架和调优,最后实现编译内核,真正意义上打造自己的Linux,如果你有兴趣,那我一起学习吧微笑强烈建议自己动手写出这六个脚本,对脚本的学习帮助非常大。

这六个脚本其实就是(一)篇的几个步骤组合起来,它们连在一起就可以完全实现(一)篇的目的,六个脚本如下:

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

#!/bin/bash #the script:rmdisk3.sh function CH { #题目要求的第二个功能 read -p "WARMING!The next action will clean the DISK!COTINUE?(Y|y.other for quite)" CH if [ $CH == 'Y' -o $CH == 'y' ];then MOUNT=`mount | grep $1` #通过grep来抓取mount里的指定磁盘,看是否被挂载 for i in $MOUNT;do #用for循环列表来一个一个卸载掉挂载的分区 i=`mount | grep /dev/sdb | awk '{print $1}'` fuser -km $i #这个命令用于剔除分区里的活动用户保证卸载 umount $i return 0 done else exit fi } function FDISK { #格式化所选磁盘为3个分区 dd if=/dev/zero of=$1 bs=512 count=1 #dd命令比较特殊它是一种特殊的复制 /dev/zero是一个特殊设备用于吐出0,它们组合起来 partprobe $1 #意思就是给指定磁盘的第0个块输出512个字节0,等于破坏掉他的bootloader和分区信息 echo ' #使用partprobe命令重读下分区,确保格式化顺利进行 n p 1 +50M n p 2 +512M n p 3 +256M t 3 82 w' | fdisk $1 &> /dev/null partprobe $1 sleep 1 #这里要睡1秒,等待系统将分区信息读入 mke2fs -j ${1}1 &> /dev/null #格式化三个分区 mke2fs -j ${1}2 &> /dev/null mkswap ${1}3 &> /dev/null } read -p "Chose a disk:" DISK #下面的是提醒用户的信息 fdisk -l $DISK | grep ^/dev for I in `fdisk -l $DISK | grep ^/dev |awk '{print $1}'`;do mount | grep "$I" if [ $? -ne 0 ];then echo "The $I is not mounted." else echo "The $I is mounted" fi done read -p "Countinue?(y|n)" P if [ $P == 'Y' -o $P == 'y' ];then CH $DISK FDISK $DISK echo -e "\033[32mThe action is suceess!\033[0m" else exit fi
二、写一个脚本,实现将上述步骤中创建的分区挂载至某目录:
1、写一个函数,接受两个参数,完成以下功能:
参数1为/boot分区对应的设备,传递至函数之后将其挂载至/mnt/boot;
参数2为/分区对应的设备,传递至函数之后将其挂载至/mnt/sysroot;
说明:上述的挂载点/mnt/boot和/mnt/sysroot如果事先不存在,需要先创建;如果事先存在,
且已经被某设备挂载使用,则需要先卸载原来挂载的设备;
2、将第一个脚本中实现的分区1和分区2传递给些函数执行;

#!/bin/bash # source /root/LX/1 #这条命令用于连接第一个脚本,可以引用它的变量,路径一定要对,/root/LX/1是我的存放路径 #目录/mnt/boot是否存在,如果不存在,创建,并挂载上磁盘。如果存在,踢掉里面的活动人员,卸载挂载的磁盘,挂载上刚格式化的分区1 function MOUNT { [ -d $A ] &> /dev/null || mkdir $A && fuser $A | umount $A &> /dev/null | mount ${DISK}1 $A sleep 1 [ -d $B ] &> /dev/null || mkdir $B && fuser $B | umount $B &> /dev/null | mount ${DISK}2 $B } A=/mnt/boot B=/mnt/sysroot MOUNT $A $B 三、写一个脚本,初始化rootfs
1、写一个函数,接受一个参数(参数为第二步骤中挂载的/mnt/sysroot),完成以下功能;
1)判断/mnt/sysroot是否存在并且如果存在是否是挂载的一个独立的分区,如果是,则继续后面的操作;否则,则提示用户错误信息,而后询问是否继续;
2)在/mnt/sysroot目录中创建如下子目录:
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;
3)将上面创建的tmp目录的权限设置为1777;
4)创建文件/mnt/sysroot/etc/inittab,内容如下:
id:3:initdefault:
si::sysinit:/etc/rc.d/rc.sysinit
5)创建文件/mnt/sysroot/etc/rc.d/rc.sysinit,内容如下:
#!/bin/bash
echo -e "\t\tWelcome to \033[31;1mLittle\033[0m Linux..."

mount -n -o remount,rw /
mount -n -a

/bin/bash
而后给此文件以执行权限;
6)创建文件/mnt/sysroot/etc/fstab,内容如下:
/dev/sda2 /ext3 defaults 0 0
/dev/sda1 /boot ext3 defaults 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
2、执行此函数

#!/bin/bash # source /root/LX/2 function ROOTFS { [ -d $B ] && ( mount | grep "$B" &> /dev/null ) || echo "ERRO!The $B is not mounted" | read -p "Countinue?(y|n)" INPUT if [ "$INPUT" == 'n' ];then #这是一个判断函数,防止意外情况发生 exit fi cd $B #创建目录 mkdir -p 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 chmod 1777 tmp cat >> etc/inittab << EOF #创建题目要求的几个文件 id:3:initdefault: si::sysinit:/etc/rc.d/rc.sysinit EOF cat >> etc/rc.d/rc.sysinit << EOF #!/bin/bash echo -e "\t\tWelcome to \033[31m;1mLittle\033[0m Linux..." mount -n -o remount,rw / mount -n -a /bin/bash EOF chmod 755 etc/rc.d/rc.sysinit cat >> etc/fstab << EOF /dev/sda2 / ext3 defaults 0 0 /dev/sda1 /boot ext3 defaults 0 0 sysfs /sys sysfs defaults 0 0 proc /proc proc defaults 0 0 EOF } ROOTFS $B
四、写一个脚本,实现二进制命令及对应库文件的拷贝:
1、写一个函数,接受两个参数(参数1为要复制的命令,参数2为复制命令对应的目标位置,如/mnt/sysroot),完成以下功能:
1)判断参数1所对应的命令是否存在;如果存在:
取得其目录路径,及命令对应的文件的名字;
而后将此命令复制到参数2对应的路径下,跟此命令原来的目录路径相同的子目录中;
比如,如果参数2为/mnt/sysroot,而命令路径为/bin/ls,则需要将ls复制到/mnt/sysroot/bin目录;如果命令路径为/usr/bin/man,则需要将man复制至/mnt/sysroot/usr/bin/中去;
2)复制命令的同时,判定此命令所依赖的库文件,而后对每一个库文件做如下操作:
取得其目录路径,及命令对应的文件的名字;
而后将此命令复制到参数2对应的路径下,跟此命令原来的目录路径相同的子目录中;但如果此库文件已经复制过,则不需要再次复制;
2、执行此函数;

#!/bin/bash # function LDD { which $1 &> /dev/null || echo "It is not exist" | retrun 5 #这里也是一个判断 DIR=`which $1 | grep -o "/.*"` #防止有别名的命令导致截取错误的路径 DIR1=`echo $DIR | sed "s@\(.*\)$1@\1@g"` [ -d $B$DIR1 ] || mkdir $B$DIR1 #如果要复制的目录不存在,创建它 [ -e $B$DIR ] || cp $DIR $B$DIR1 #如果文件不存在才复制它 for I in `ldd $DIR | grep -o "/[^[:space:]]*"`;do #这里使用ldd命令指定命令的执行文件存放路径,并通过for循环来复制它的库文件 DIR1=`echo $I | sed "s@\(.*\)/[^/]*@\1@g"` [ -d $B$DIR1 ] || mkdir $B$DIR1 #这里的判断同上 [ -e $B$I ] || cp $I $B$DIR1 << End n End done } B=/mnt/sysroot read -p "Which command you want add:" COM LDD $COM
五、写一个脚本,实现引导分区的设定:
1、写一个函数,接受一个参数(参数为目标Linux的boot目录),实现以下功能:
1)创建一个临时目录/tmp/litte.XX;
2)将宿主机的/boot/initrd-`uname -r`.img文件展开至临时目录;
3)修改展开而来的init文件:
a)注释掉如下行:
echo Scanning and configuring dmraid supported devices
echo Scanning logical volumes
lvm vgscan --ignorelockingfailure
echo Activating logical volumes
lvm vgchange -ay --ignorelockingfailure vol0
resume LABEL=SWAP-sda3
b)将如下行中的设备修改为你所需要的:
mkrootdev -t ext3 -o defaults,ro /dev/vol0/root
4)将修改好的内容重新封闭为cpio的归档文件,并gzip压缩后存放至参数所指定的目录;
5)复制/boot/vmlinuz-`uname -r`至参数所指定的目录,并重命令为vmlinuz;
2、执行此函数;
3、说明:此处的`uname -r`只是为了引用当前系统正在使用的内核和initrd文件,但这并非是必须。即如果你有其它内核和对应的initrd文件,也可使用。

#!/bin/bash # source /root/LX/3 KERNEL=vmlinuz INITRD=initrd.gz function BOOT { #这个函数解开initrd文件,并写入信息后重新归档封装 DIR=`mktemp -d /tmp/litte.XX` #创建临时目录 cd $DIR zcat /boot/initrd-`uname -r`.img | cpio -id #释放initrd到一个临时目录 sed -i 's@echo Scanning and configuring dmraid supported devices@#&@g' init #修改 sed -i 's@echo Scanning logical volumes@#&@g' init sed -i 's@lvm vgscan --ignorelockingfailure@#&@g' init sed -i 's@echo Activating logical volumes@#&@g' init sed -i 's@lvm vgchange -ay --ignorelockingfailure vol0@#&@g' init sed -i 's@resume LABEL=SWAP-sda3@#&@g' init sed -i "s@\(mkrootdev.* \).*@\1${DISK}2@g" init find . | cpio -H newc -o --quiet | gzip -9 > $1/initrd.gz #再次归档压缩 CP /Boot/vmlinuz-`uname -r` $1/vmlinuz #复制修改并归档后的initrd文件到我们的小linux /boot里 rm -rf $DIR #要养成删临时文件的好习惯 } BOOT $A
六、写一个脚本,为目标主机所以磁盘设定grub:
1、写一个函数,接受四个参数(参数1为目标磁盘,参数2为引导分区的挂载点,参数3为内核文件名,参数4为initrd文件名),完成以下功能:
1)判断挂载点路径的基名是否为boot,如果不是,则停止执行,并提示用户修改;否则,则继续下面的操作;
2)向目标磁盘安装grub;
3)在参数3中的子目录grub下建立文件grub.conf;内容类似如下内容:
default=0
timeout=10
title Little Linux
root (hd0,0)
kernel /$3
initrd /$4
2、执行此函数

#!/bin/bash # source /root/LX/5 function GRUB { [ `basename $2` != boot ] && echo "The mounted dir is wrong!Modiy it!" && exit #判断,防止出错 grub-install --root-directory=/mnt/ $1 &> /dev/null #安装grub cat >> $2/grub/grub.conf << EOF #创建grub.conf文件 default=0 timeout=10 title Little Linux root (hd0,0) kernel /$3 ro root=${DISK}2 quite initrd /$4 EOF } GRUB $DISK $A $KERNEL $INITRD

好了,就是这6个脚本~写出来后对自己的帮助非常大!


下篇预告:打造自己的专属Linux(三):给小linux添加网络模块,实现关机重启,登录界面











  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值