1、請詳細描述CentOS系統的啟動流程(詳細到每個過程系統做了哪些事情)
從dawning大濕兄那里借來的圖,如下:
啟動過程 (PC架構) POST –> Boot Sequence(BIOS) –> Boot Loader (MBR)–>GRUB—> Kernel(ramdisk) –> rootfs –> switchroot –> /sbin/init–>(/etc/inittab, /etc/init/*.conf) –> 設定默認運行級別> 系統初始化腳本 –> 關閉或啟動對應級別下的服務 –> 啟動終端
第一步:加電自檢(POST)
系統加電之后,首先進行的硬件自檢,一但通電后主板會自動讀取ROM(只讀)中的程序,進行加載,計算機會首先加載BIOS信息,BIOS信息是如此的重要,以至于計算機必須在最開始就找到它。檢查各種硬件設備是否完整存在,如內存,硬盤,顯示,IO設備等。如果有硬件故障的話將按兩種情況理:對于嚴重故障(致命性故障)則停機,此時由于各種初始化操作還沒完成,不能給出任何提示或信號;對于非嚴重故障則給出提示或聲音報警信號,等待用戶處理),如果沒有故障,POST完成自己 的接力任務,將尾部工作交接給BIOS處理。
第二步:系統引導過程Boot Sequence(BIOS)
POST 過程結束后,系統的控制權從 BISO 轉交到 boot loader。Boot loader 一般存儲在系統的硬盤上(傳統的 BIOS/MBR 系統),這個時候機器不能獲取外部的存儲或者網絡信息,一些重要的值(日期、時間、其他外部值)都是從CMOS里讀取.
POST(POST-power on self test)—>ROM->CMOS(互補金屬氧化物)->BIOS (Basic Input Output System,基礎輸入輸出系統)
BIOS(Basic Input/Output System)啟動初始化硬件的工作,包括屏幕和鍵盤,內存檢測,這個過程也被成為 POST(Power On Self Test),通過ROM加載自檢程序,然后按照 CMOS RAM 中設置的啟動設備查找順序,來尋找可啟動設備 。注:BIOS 程序嵌在主板的 ROM 芯片上的。
第三步:啟動加載器階段Master Boot Loader(MBR)
硬盤上第0磁道第一個扇區被稱為MBR,也就是Master Boot Record,即主引導記錄,決定啟動介質按照BIOS所設定的系統啟動流程,根據引導次序(Boot Sequence)自上而下的尋找對應存儲設備上操作系統的MBR。它的大小僅有512字節,但里面卻存放了預啟動信息、分區表信息??煞譃閮刹糠郑?
第一部分為引導(PRE-BOOT)區,占了 446個字節;
第二部分為分區表(PARTITION TABLE),共有64個字節,每個主分區占用16字節,記錄硬盤的分區信息。(這就是為什么一塊硬盤只能有4個主分區)分區表有效性標記會占用2字節。
預引導區的作用之一是找到標記為活動(ACTIVE)的分區,并將活動分區的引導區讀入內存。剩余兩個字節為結束標記。尋找 grub,讀取配置文件/etc/grub.conf,決定默認啟動項根據MBR所指引的活動分區上尋找系統分區中的 bootloader.在bootloader當中配置了所要引導操作系統的內核所在的位置,因此BIOS被載入內存以后,當它實現將控制權限轉交給bootloader以后,bootloader接收整個系統的控制權限,而后根據用戶的選擇去讀取相應操作系統中的內核,并將內核裝載入內存的某個空間位置,解壓縮,這時kernel就可以在內存中活動,并根據kernel本身功能在內存當中探索硬件并加載硬件驅動程序并完成內核初始化,bootloader會將控制權限轉交給內核。
第四步:引導加載器階段(GRUB加載器)
對于GRUB來說,一個比較好的方面就是它包含了linux文件系統的支持。GRUB能夠從ext2或者ext3文件系統中加載linux內核。一旦Bootloader的第一階段已完成MBR(啟動加載器階段),并能找到實際的引導加載程序位置,第1階段啟動加載器加載引導程序到內存中開始第二階段。GRUB引導加載器階段它是通過將本來兩階段的boot loader轉換成三個階段的boot loader。
stage1個階段 :BIOS加載MBR里面的GRUB(屬于第1階段的文件),由于只有GRUB只占用446字節所以不能實現太多的功能,所以就有此階段里面的文件來加載第1.5階段的文件(/boot/grub下的文件)
stage1.5個階段:這個階段里面的就是加載識別文件系統的程序,來識別文件系統,不加載就無法識別文件系統,進而就找不到boot目錄,由于GRUB是無法識別LVM,所以你不能把/boot分區設置為LVM,所以必須要把/boot單獨分區
stage2個階段:這里面才是正在的開始尋找內核的過程,然后是啟動內核
(當stage1.5的boot loader被加載并運行時,stage2 的boot loader才能被加載。)
當stage2被加載時,GRUB能根據請求的情況顯示一個可選內核的清單(在 /etc/grub.conf 中進行定義,同時還有幾個軟符號鏈接 /etc/grub/menu.lst 和 /etc/grub.conf)。你可以選擇一個內核,修改其附加的內核參數。同時,你可以選擇使用命令行的shell來對啟動過程進行更深層次的手工控制。
GRUB的配置文件中的配置哪些信息
在第二階段boot loader加載到內存中后,就可以對文件系統進行查詢了,同時,默認的內核鏡像以及初始化內存盤鏡像也被加載到內存中。
根據grub設定的內核映像所在路徑,系統讀取內存映像,并進行解壓縮操作。此時,屏幕一般會輸出“Uncompressing Linux(解壓內核中)”的提示。當解壓縮內核完成后,屏幕輸出“OK, booting the kernel(正在啟動內核)”。
**第五步:加載kernel **
GRUB把內核加載到內存后展開并運行,此時GRUB的任務已經完成,接下來內核將會接管并完成:
探測硬件—>加載驅動—>掛載根文件系統—>切換至根文件系統(rootfs)—>運行/sbin/init完成系統初始化
內核一般都是壓縮的,所以它的首要任務是解壓縮,然后檢查和分析系統的硬件并初始化內核里的硬件驅動程序。內核剛加載到內存的時候,文件系統還不能使用,它使用的是 Boot Loader 加載進內存的 initramfs。系統將解壓后的內核放置在內存之中,并調用start_kernel()函數來啟動一系列的初始化函數并初始化各種設備,完成Linux核心環境的建立。至此,Linux內核已經建立起來了,基于Linux的程序應該可以正常運行了。
第六步:初始化initrd /etc/inittab
在核心加載完畢,進行完硬件偵測與驅動程序加載后,內核會啟動第一個進程/sbin/init, init進程將會讀取/etc/inittab,init進程是系統所有進程的起點,你可以把它比擬成系統所有進程的老祖宗,沒有這個進程,系統中任何進程都不會啟動。
/etc/inittab最主要的功能就是準備軟件運行的環境,包括系統的主機名稱、網絡配置、語系處理、文件系統格式及其他服務的啟動等,而所有的動作都根據在/etc/inittab中的配置.將會執行/etc/inittab來設定系統運行的默認級別,
init進程首先會讀取/etc/inittab文件,根據inittab文件中的內容依次執行 設定系統運行的默認級別(id:3:initdefault:) 執行系統初始化腳本文件(si::sysinit:/etc/rc.d/rc.sysinit) 執行在該運行級別下所啟動或關閉對應的服務(l3:3:wait:/etc/rc.d/rc 3) 啟動6個虛擬終端
0-6:7個級別的定義
0:關機, shutdown
1:單用戶模式(singleuser),root用戶,無須認證;維護模式;
2:多用戶模式(multiuser),會啟動網絡功能,但不會啟動NFS;維護模式;
3:多用戶模式(mutliuser),完全功能模式;文本界面;
4:預留級別:目前無特別使用目的,但習慣以同3級別功能使用;
5:多用戶模式(multi user),完全功能模式,圖形界面;
6:重啟,reboot
許多程序需要開機啟動。它們在Windows叫做”服務”(service),在Linux就叫做”守護進程”(daemon)。init進程的一大任務,就是去運行這些開機啟動的程序。但是,不同的場合需要啟動不同的程序,比如用作服務器時,需要啟動Apache,用作桌面就不需要。
Linux允許為不同的場合,分配不同的開機啟動程序,這就叫做”運行級別”(runlevel)。也就是說,啟動時根據”運行級別”,確定要運行哪些程序。
要訪問根文件系統必須要加載根文件系統所在的設備,而這時根文件系統又沒有掛載,要掛載根文件系統有需要根文件系統的驅動程序,這是一個典型的先有雞先有蛋的問題!為解決這個問題,GRUB在加載內核同時,也把initrd加載到內存中并運行.那么initrd又起到了什么作用哪?
initrd展開后的文件
linux中/下的文件
我們可以看到,其實initrd文件其實是一個虛擬的根文件系統,里面有bin、lib、lib64、sys、var、etc、sysroot、dev、proc、tmp等根目錄,它的功能就是講內核與真正的根建立聯系,內核通過它加載根文件系統的驅動程序,然后以讀寫方式掛載根文件系統,至此,內核加載完成。
第七步:運行/sbin/init,進行系統初始化
/sbin/init 最主要的功能就是準備軟件運行的環境,包括系統的主機名稱、網絡配置、語系處理、文件系統格式及其他服務的啟動等,而所有的動作都根據在/etc/inittab中的配置.init首先運行/etc/init/rcS.conf腳本,如下圖
第八步:啟動系統服務/etc/rc.d/rc.sysinit
可以看到,init進程通過執行/etc/rc.d/rcS.conf首先調用了/etc/rc.d/rc.sysinit,對系統做初始化設置,設置好整個系統環境。我們來看看這個腳本都是做了些什么哪?
事實上init執行/etc/rc.d/rc.sysinit的初始化將會做很多設置:
1、獲得網絡環境 2、掛載設備 3、開機啟動畫面Plymouth(取替了過往的 RHGB) 4、判斷是否啟用SELinux 5、顯示于開機過程中的歡迎畫面 6、初始化硬件 7、用戶自定義模塊的加載 8、配置內核的參數 9、設置主機名 10、同步存儲器 11、設備映射器及相關的初始化 12、初始化軟件磁盤陣列(RAID) 13、初始化 LVM 的文件系統功能 14、檢驗磁盤文件系統(fsck) 15、設置磁盤配額(quota) 16、重新以可讀寫模式掛載系統磁盤 17、更新quota(非必要) 18、啟動系統虛擬隨機數生成器 19、配置機器(非必要) 20、清除開機過程當中的臨時文件 21、創建ICE目錄 22、啟動交換分區(swap) 23、將開機信息寫入/var/log/dmesg文件中
第九步:啟動配置文件/etc/rc.d/rc.n
設定玩系統默認運行級別以后,接著調用/etc/rc.d/rc腳本,/etc/rc.d, 里面存放了rc.local, rc.sysinit, init.d, rcX.d (X包括0-6對應相對runlevel).這個腳本接收默認運行級別參數后,依腳本設置啟用或停止/etc/rc.d/rc[0-6].d/中相應的程序。
/etc/rc.d/rc3].d/下的腳本文件在系統初始化階段,腳本名字以K開頭的,表示STOP動作(關閉),名字以S開頭,表示Start動作(啟動),文件名K/S 后面的的數字代表優先級,名稱中的數字表示執行次序(優先級),數字越小表示越先執行,優先級越高
第十步:用戶自定義開機啟動程序 (/etc/rc.d/rc.local)
系統根據runlevel啟動完rcX.d中的腳本之后,會調用rc.local腳本,如果你有一個腳本命令不論在3和5都想開機啟動,那么就添加于此,免去rc3.d和rc5.d分別增加啟動腳本工作量.最后,將執行/etc/rc.d/rc.local腳本,可以根據自己的需求將一些執行命令或者腳本寫到其中,當開機時就可以加載。
第十一步:打印登錄提示符
系統初始化完成后,init給出用戶登錄提示符(login)或者圖形化登錄界面,用戶輸入用戶和密碼登陸后,系統會為用戶分配一個用戶ID(uid)和組ID(gid),這兩個ID是用戶的身份標識,用于檢測用戶運行程序時的身份驗證。登錄成功后,整個系統啟動流程運行完畢!
2、為運行于虛擬機上的CentOS 6添加一塊新硬件,提供兩個主分區;
(1) 為硬盤新建兩個主分區;并為其安裝grub; (2) 為硬盤的第一個主分區提供內核和ramdisk文件; 為第二個分區提供rootfs; (3) 為rootfs提供bash、ls、cat程序及所依賴的庫文件; (4) 為grub提供配置文件; (5) 將新的硬盤設置為第一啟動項并能夠正常啟動目標主機;
為硬盤新建兩個主分區
[root@centos ~]# fdisk -l #先來看看磁盤情況啊,你不看,一上來直接搞,小心搞出事情??! Disk /dev/sda: 171.8 GB, 171798691840 bytes 255 heads, 63 sectors/track, 20886 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00098b32 Device Boot Start End Blocks Id System /dev/sda1 * 1 64 512000 83 Linux Partition 1 does not end on cylinder boundary. /dev/sda2 64 20887 167259136 8e Linux LVM Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Disk /dev/mapper/vg_centos-lv_root: 170.2 GB, 170196467712 bytes 255 heads, 63 sectors/track, 20691 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Disk /dev/mapper/vg_centos-lv_swap: 1073 MB, 1073741824 bytes 255 heads, 63 sectors/track, 130 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000
不錯不錯,看到sdb了, 分的40G
開始分區
[root@centos ~]# fdisk /dev/sdb Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x86662f67 Device Boot Start End Blocks Id System Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-5221, default 1): Using default value 1 Last cylinder, +cylinders or +size{K,M,G} (1-5221, default 5221): +20G Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x86662f67 Device Boot Start End Blocks Id System /dev/sdb1 1 2612 20980858+ 83 Linux Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 2 First cylinder (2613-5221, default 2613): Using default value 2613 Last cylinder, +cylinders or +size{K,M,G} (2613-5221, default 5221): Using default value 5221 Command (m for help): p Disk /dev/sdb: 42.9 GB, 42949672960 bytes 255 heads, 63 sectors/track, 5221 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x86662f67 Device Boot Start End Blocks Id System /dev/sdb1 1 2612 20980858+ 83 Linux /dev/sdb2 2613 5221 20956792+ 83 Linux Command (m for help): w The partition table has been altered!
分區完了就開始格式化了啊
[root@centos ~]# mkfs.ext4 /dev/sdb1 mke2fs 1.41.12 (17-May-2010) 文件系統標簽= 操作系統:Linux 塊大小=4096 (log=2) 分塊大小=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 1313760 inodes, 5245214 blocks 262260 blocks (5.00%) reserved for the super user 第一個數據塊=0 Maximum filesystem blocks=4294967296 161 block groups 32768 blocks per group, 32768 fragments per group 8160 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 正在寫入inode表: 完成 Creating journal (32768 blocks): 完成 Writing superblocks and filesystem accounting information: 完成 This filesystem will be automatically checked every 21 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override. [root@centos ~]# mkfs.ext4 /dev/sdb2 mke2fs 1.41.12 (17-May-2010) 文件系統標簽= 操作系統:Linux 塊大小=4096 (log=2) 分塊大小=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 1310720 inodes, 5239198 blocks 261959 blocks (5.00%) reserved for the super user 第一個數據塊=0 Maximum filesystem blocks=4294967296 160 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 正在寫入inode表: 完成 Creating journal (32768 blocks): 完成 Writing superblocks and filesystem accounting information: 完成 This filesystem will be automatically checked every 26 mounts or 180 days, whichever comes first. Use tune2fs -c or -i to override.
掛載分區sdb1到/mnt/boot下
[root@centos mnt]#mkdir boot [root@centos mnt]#mount /dev/sdb1 /mnt/boot
安裝grub
[root@centos mnt]# grub-install --root-de [root@centos mnt]# grub-install --root-directory=/mnt /dev/sdb Probing devices to guess BIOS drives. This may take a long time. /dev/mapper/vg_centos-lv_root does not have any corresponding BIOS drive. [root@centos mnt]# ll 總用量 8 drwxr-xr-x 3 root root 4096 2月 20 10:09 boot drwxr-xr-x 2 root root 4096 10月 18 10:41 hgfs [root@centos mnt]#
復制內核及ramdisk文件到sdb1上
[root@centos mnt]# cp /boot/vmlinuz-2.6.32-642.13.1.el6.x86_64 /mnt/boot/vmlinuz [root@centos mnt]# cp /boot/initramfs-2.6.32-642.13.1.el6.x86_64.img /mnt/boot/initramfs.img
在/mnt/boot/grub目錄下編輯新建grub.conf文件
內容如下:
default=0 timeout=5 title CentOS6(test) root (hd0,0) kernel /vmlinuz ro root=/dev/sda2 selinux=0 init=/bin/bash initrd /initramfs.img
掛載分區/dev/sdb2到/mnt/sysroot下
mkdir /mnt/sysroot mount /dev/sdb2 /mnt/sysroot/
建立FHS
[root@centos sysroot]# mkdir -pv /mnt/sysroot/{bin,dev,etc/{rc.d/init.d,sysconfig/network-scripts},lib/modules,lib64,proc,sbin,sys,tmp,usr/local/{bin,sbin},var/{lock,log,run}} mkdir: 已創建目錄 "/mnt/sysroot/bin" mkdir: 已創建目錄 "/mnt/sysroot/dev" mkdir: 已創建目錄 "/mnt/sysroot/etc" mkdir: 已創建目錄 "/mnt/sysroot/etc/rc.d" mkdir: 已創建目錄 "/mnt/sysroot/etc/rc.d/init.d" mkdir: 已創建目錄 "/mnt/sysroot/etc/sysconfig" mkdir: 已創建目錄 "/mnt/sysroot/etc/sysconfig/network-scripts" mkdir: 已創建目錄 "/mnt/sysroot/lib" mkdir: 已創建目錄 "/mnt/sysroot/lib/modules" mkdir: 已創建目錄 "/mnt/sysroot/lib64" mkdir: 已創建目錄 "/mnt/sysroot/proc" mkdir: 已創建目錄 "/mnt/sysroot/sbin" mkdir: 已創建目錄 "/mnt/sysroot/sys" mkdir: 已創建目錄 "/mnt/sysroot/tmp" mkdir: 已創建目錄 "/mnt/sysroot/usr" mkdir: 已創建目錄 "/mnt/sysroot/usr/local" mkdir: 已創建目錄 "/mnt/sysroot/usr/local/bin" mkdir: 已創建目錄 "/mnt/sysroot/usr/local/sbin" mkdir: 已創建目錄 "/mnt/sysroot/var" mkdir: 已創建目錄 "/mnt/sysroot/var/lock" mkdir: 已創建目錄 "/mnt/sysroot/var/log" mkdir: 已創建目錄 "/mnt/sysroot/var/run" [root@centos sysroot]#
拷貝bash、ls、cat程序及其依賴庫
[root@centos sysroot]# cp /bin/{bash,ls,cat} /mnt/sysroot/bin [root@centos bin]# cp `ldd /bin/{bash,ls,cat} |grep -oe "/lib.*[[:space:]]"|sort -u` /mnt/sysroot/lib64/ [root@centos bin]# chroot /mnt/sysroot
chroot先測試一下
[root@centos bin]# chroot /mnt/sysroot bash-4.1# ls bin dev etc lib lib64 proc sbin sys tmp usr var bash-4.1# exit exit [root@centos bin]#
OK,接下來掛載到另外一臺虛擬機上測試一下,親測成功。
3、制作一個kickstart文件以及一個引導鏡像。描述其過程。
思路
- 找到一個已安裝好的centos的ks文件,一般位于/root/anaconda-ks.cfg,修修改改,生成一個自定義的ks.cfg文件。
- 放到解壓的原版IOS到某目錄,添加ks文件。
- 修改光盤的isolinux.cfg文件,在 append 指令后附加 ks 設置。
- 再生成自定義的ISO文件。
- 最后用此ISO去安裝啟動一臺裸虛擬機測試是否能自動安裝。
找到一個已安裝好的centos的ks文件,一般位于/root/anaconda-ks.cfg,修修改改,生成一個自定義的ks.cfg文件
#platform=x86, AMD64, 或 Intel EM64T #version=DEVEL # Firewall configuration firewall --disabled # Install OS instead of upgrade install # Use CDROM installation media cdrom # Root password rootpw --iscrypted $1$Qo3PJbQH$GyTUtGgr1U.th4KTIrvfT1 # System authorization information auth --useshadow --passalgo=sha512 # Use graphical install graphical firstboot --disable # System keyboard keyboard us # System language lang zh_CN # SELinux configuration selinux --disabled # Installation logging level logging --level=info # System timezone timezone Asia/Shanghai # Network information network --bootproto=dhcp --device=eth1 --onboot=on # System bootloader configuration bootloader --location=mbr # Partition clearing information clearpart --all --initlabel # Disk partitioning information part /boot --fstype="ext4" --size=500 part swap --fstype="swap" --size=2000 part / --fstype="ext4" --grow --size=1 %packages @base @compat-libraries @graphical-admin-tools @legacy-unix @network-tools @xfce-desktop NetworkManager-openswan arptables_jf arpwatch audit-viewer authd cups-lpd dbench dropwatch dump ebtables ettercap finger finger-server firstaidkit-gui ipset iptraf iptstate krb5-appl-servers ksh lksctp-tools lshw-gui mipv6-daemon mksh mrtg ncompress netlabel_tools nmap openvpn policycoreutils-gui qstat rsh rsh-server rusers rusers-server rwho sabayon setroubleshoot stunnel system-config-kickstart system-config-lvm talk talk-server tcp_wrappers telnet telnet-server tftp vtun wireshark wireshark-gnome yumex -cpuspeed -irqbalance -mdadm %end
放到解壓的原版IOS到某目錄,添加ks文件
我這里是用軟碟通直接提取修改,所以就神略了
還有一個坑就是ks配置文件里面用cdrom參數制定本地光盤安裝會報錯,建議用url方式。這個坑踩得我受傷了,就不寫了。
4、寫一個腳本
(1) 能接受四個參數:start, stop, restart, status start: 輸出“starting 腳本名 finished.” …
(2) 其它任意參數,均報錯退出;
#!/bin/bash # case $1 in start) echo "starting $0 finished" ;; stop) echo "stopping $0 finished" ;; restart) echo "restarting $0 finished" ;; status) echo " $0 status" ;; *) echo "Usage: $prog {start|stop|restart|status}" exit 1 ;; esac
5、寫一個腳本,判斷給定的用戶是否登錄了當前系統;
(1) 如果登錄了,則顯示用戶登錄,腳本終止;
(2) 每3秒鐘,查看一次用戶是否登錄;
#!/bin/bash # until who | grep "^logstash\>" &> /dev/null; do sleep 3 done
6、寫一個腳本,顯示用戶選定要查看的信息;
cpu) display cpu info
mem) display memory info
disk) display disk info
quit) quit
非此四項選擇,則提示錯誤,并要求用戶重新選擇,只到其給出正確的選擇為止;
#!/bin/bash # cat << EOF Display information as following shown selection cpu) display cpu info mem) display memory info disk) display disk info quit) quit ************************************************ EOF while true; do read -p "Please input your selection: " selection case $selection in cpu) lscpu ;; mem) free -m ;; disk) fdisk -l /dev/vd[a-z] ;; quit) echo "Bye Bye" exit 0 ;; *) echo "Please input valid selection" ;; esac done
7、寫一個腳本
(1) 用函數實現返回一個用戶的UID和SHELL;用戶名通過參數傳遞而來;
(2) 提示用戶輸入一個用戶名或輸入“quit”退出;
當輸入的是用戶名,則調用函數顯示用戶信息;
當用戶輸入quit,則退出腳本;進一步地:顯示鍵入的用戶相關信息后,再次提醒輸出用戶名或quit:
#!/bin/bash # userInfo() { local userLine=$(grep $1 /etc/passwd) local userSHELL=${userLine##*:} local userID=$(echo $userLine | cut -f3 -d:) echo "$userSHELL and $userID" } quit() { if [ "$1" == "quit" ]; then echo "Bye Bye" exit 2 fi } while true; do read -p "Please input your username or input 'quit': " choice if [ "$choice" == "quit" ]; then quit $choice break fi if id $choice >& /dev/null; then userInfo $choice fi done
8、寫一個腳本,完成如下功能(使用函數)
(1) 提示用戶輸入一個可執行命令的名字;獲取此命令依賴的所有庫文件;
(2) 復制命令文件至/mnt/sysroot目錄下的對應的rootfs的路徑上,例如,如果復制的文件原路徑是/usr/bin/useradd,則復制到/mnt/sysroot/usr/bin/目錄中;
(3) 復制此命令依賴的各庫文件至/mnt/sysroot目錄下的對應的rootfs的路徑上;規則同上面命令相關的要求;
#!/bin/bash read -p "Please input a command: " cmd cmdPath=$(which $cmd | grep bin) cpCmd() { cp $cmdPath /mnt/sysroot$cmdpath echo "Copy $cmdPath to path /mnt/sysroot/" } cpFile() { libFile=$(ldd $cmdPath | grep -o "/[^[:space:]]\{1,\}") for i in $libFile; do cp $lib /mnt/sysroot$cmdPath echo "Copy $libFile to path/mnt/sysroot/$cmdPath" done } cpCmd cpFile
原創文章,作者:N24_Jerry,如若轉載,請注明出處:http://www.www58058.com/69928
寫的很好,請注意路徑的書寫,有的地方寫錯了比如說在第九步時。