Shell 編 程 之 until循 環 語 句
§·練習題:
1 每隔3秒鐘到系統上獲取已經登錄的用戶的信息;如果發現用戶hacker登錄,則將登錄時間和主機記錄于日志/var/log/login.log中,并提示該用戶退出系統?
解:解題思路:按照題意該腳本一直無限循環,一直探測用戶hacker使用登錄,w 命令可以顯示當前登錄的用戶,在通過 grep查找該用戶,查找到就提示該用戶需要注銷下線。
until的循環語句是判斷為假就執行循環體,一定要記得不要寫反了。
腳本內容如下:
#!/bin/bash until false ; do #創建until無限循環 until ! w | grep -o "^hacker" &>/dev/null ; do #判斷hacker如果登錄就提示該用戶必須下線 who | grep "^hacker" > /var/log.log && echo "Your must login out" | write hacker echo "hacker loging ........" sleep 3 done until w| grep -o "^hacker" &>/dev/null ; do #判斷hacker用戶沒有登錄,就提示該用戶沒有登錄 echo "hacker no login.........." sleep 3 done done
解:解題思路:根據題意,我們需要寫一個無限循環,當用戶輸入的數字與隨機數相等,循序就退出。用戶輸入的數字大于隨機數,提示用戶輸入的數字大了,,并且讓用戶重新輸入;如果用戶輸入的數字小于隨機數,提示用戶輸入的數字小了,并且重新輸入。
腳本內容如下:
#!/bin/bash cat << EOF guess number please input ini number! #顯示一個提示信息 EOF let guess=$[$RANDOM%9+1] #定義一個guess變量,為隨機生成的數字 read -p "you guess bumber: " innum #提示用戶輸入一個用戶猜測的數字 until false ;do #編寫一個無限循環的until until expr $innum + 100 &>/dev/null ;do cat << EOF guess number please input 0 1 2 ... 8 9 10 between ini number! EOF read -p "you guess number: " innum #用戶輸入的不是數字,提示用戶輸入正確的數字 done if [ $innum -eq $guess ] ;then #判斷用戶輸入的數字與隨機數的是否相等,相等則退出,并顯示信息 echo "you guess right " echo "Random number is : $guess" exit 0 elif [ $innum -lt $guess ] ; then #判斷用戶輸入的數字是否小于隨機數,小于提示重新輸入, echo "you guess number is too little" read -p "you guess number: " innum else #其它信息為用戶輸入數據大于隨機數,提示用戶重新輸入 echo "you guess number is too big" read -p "you guess number: " innum fi done
3 編寫腳本,求100以內所有正整數之和?
解:解題思路:申明一個變量 i在1到100直接循序,把i的值每一次的值加到變量sum中,最后輸出sum的 值即可。 腳本內容如下: #!/bin/bash let i=1 let sum=0 until [ $i -gt 100 ] ;do sum=$[sum+i] let i++ done echo "$sum "
1、編寫腳本,通過ping命令探測10.1.0.240-254范圍內的所有主機的在線狀態,統計在線主機和離線主機各多少?
解:解題思路:申明一個變量i在240到254直接循環,申明uphost downhost統計在線和離線的主機數量。
通過ping -c1 -W1 10.1.0.$i 返回值判斷主機在不在線。
腳本內容如下: #!/bin/bash let i=240 let uphost=0 let downhost=0 until [ $i -gt 254 ]; do if ping -c1 -W1 10.1.0.$i &>/dev/null ;then echo "host 10.1.0.$i is : up" let uphost++ else echo "host 10.1.0.$i is : donw " let downhost++ fi let i++ done echo "up host number is :$uphost" echo "down host number is :$downhost"
4 編寫腳本,打印九九乘法表?
解:解題思路:分析99乘法表,一共九行,每行的數量是行數號,如下圖。
行為n行,每行為n個算術表達式(每行表達式循環行號的個數)
申明總共行數為:n ,每行循序的個數為m
每行的表達式為:n*1 到 n*n
[root@Centos7 for_shells]# bash no3_while.sh 1*1=1 (第1行,該行1個表達式) 1*2=2 2*2=4 (第2行,該行2個表達式) 1*3=3 2*3=6 3*3=9 (第3行,該行3個表達式) 1*4=4 2*4=8 3*4=12 4*4=16 (第4行,該行4個表達式) 1*5=5 2*5=10 3*5=15 4*5=20 5*5=25 (第5行,該行5個表達式) 1*6=6 2*6=12 3*6=18 4*6=24 5*6=30 6*6=36(第6行,該行6個表達式) 1*7=7 2*7=14 3*7=21 4*7=28 5*7=35 6*7=42 7*7=49(第7行,該行7個表達式) 1*8=8 2*8=16 3*8=24 4*8=32 5*8=40 6*8=48 7*8=56 8*8=64(第8行,該行8個表達式) 1*9=9 2*9=18 3*9=27 4*9=36 5*9=45 6*9=54 7*9=63 8*9=72 9*9=81(第9行,該行9個表達式)
腳本內容如下:
#!/bin/bash let a=1 while [ $ a -le 9 ] ; do #需要循序的行數 let b=1 while [ $b -le $a ]; do #每行的算術表達式的個數 let sum=$a*$b echo -ne " $b*$a=$sum\t" #每次顯示的表達式的結果 let b++ done echo "" let a++ done
5 編寫腳本,利用變量RANDOM生成10個隨機數字,輸出這個10數字,并顯示其中的最大者和最小者?
解:解題思路:讓程序開始就生成兩個隨機數,保存在變量max與min中,首先比較max與min的大小,較大值保存在max中,較小值保存在min中,再隨機生成的8個變量我們需要使用臨時變量ran存儲它的數字,讓ran與我們的max與min比較,ran比max大把值給max,ran比min小,把值給min,即可實現我們需要的要求。
#!/bin/bash # let i=1 max=$[$RANDOM] #生成隨機值保存在max中 min=$[$RANDOM] #生成隨機值保存在min中 [ $max -lt $min ]&&let linshi=$min&&let min=$max&&let max=$linshi #比較max與min大小,保證max的值最大 echo "random number 1 is : $max ." echo "random number 2 is : $min . " while [ $i -le 8 ] ; do #循環8次,每次生成一個隨機數ran,讓ran與max min比較大小。 ran=$[$RANDOM] [ $max -lt $ran ]&& let max=$ran #ran比max大,max為ran的值,保證max為最大值 [ $min -gt $ran ]&& let min=$ran #ran比min小,min為ran的值,保證min為最小值 let i++ done echo "=======================" echo "max number is : $max ." echo "min number is : $min ."
6 編寫腳本,實現打印國際象棋棋盤?
解:解題思路,國際象棋棋盤為8行8列,第1格背景色為紅(比如),第2格背景色為白,如此交替。
我們打印8行8列的帶背景的空格應該是沒有問題的,問題就是如何讓它背景顏色可交替下去。
我們觀察我們需要打印的棋盤,第一行為奇數行為紅色,第二行為偶數行,如此交替。
如果定義一個變量c,c與2的余數為1時打印紅色,為0時打印白色,第一行沒有問題,如果我們在每 行的換行的時候讓c再加1,那我們第二行也可以遵循c與2的余數為1時打印紅色,為0時打印白色; 就可以一次循序下去。
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
腳本內容如下: #!/bin/bash let a=1 let b=1 let c=1 while [ $a -le 8 ] ; do #行的循序次數 let b=1 while [ $b -le 8 ] ; do #列的循序次數 let yushu=$c%2 #紅白交替的余數控制,變量為c if [ $yushu -eq 1 ] ;then echo -e "\033[47m \033[0m\c" # else echo -e "\033[41m \033[0m\c" fi let c++ let b++ done echo "" #換行符 let c++ #換行后記得讓c再加1 let a++ done
解:解題思路:需要打印的為下圖所示,主要有空格和*號組成,主要在于空格和*號的數量,我們分析圖形可以得到一些規律:
對于紅色部分:(由于我*號用空格隔開了,所以與正常有點不一樣,不過通過觀察還是可以得出差不多的規律)
如果有7行(n行)
通過規律我們就可以添加我們的空格和*號數量,
黑色部分同理,也可以得出規律
行數(i) |
空格數 |
星數 |
總行數(n) |
1 |
12(2n-2i) |
1(2i-1) |
7(n) |
2 |
10(2n-2i) |
3(2i-1) |
7(n) |
3 |
8(2n-2i) |
5(2i-1) |
7(n) |
4 |
6(2n-2i) |
7(2i-1) |
7(n) |
5 |
4(2n-2i) |
9(2i-1) |
7(n) |
6 |
2(2n-2i) |
11(2i-1) |
7(n) |
7 |
0(2n-2i) |
13(2i-1) |
7(n) |
*
* * *
* * * * *
* * * * * * *
* * * * * * * * *
* * * * * * * * * * *
* * * * * * * * * * * * *
* * * * * * * * * * *
* * * * * * * * *
* * * * * * *
* * * * *
* * *
*
#等腰三角形的上半部分
#!/bin/biash let a=1 let b=1 let n=10 for i in `seq 1 $n`;do for a in `seq 1 $[ 2*(n-i) ]` ;do echo -n " " let a++ done for b in `seq 1 $[ 2*i-1 ]`; do echo -ne "\033[33m* \033[0m" let b++ done echo " " let i++ done
#等腰三角形的下半部分
let j=1 let aa=1 let bb=1 let nt=$[n-1] for j in `seq 1 $nt` ; do for aa in `seq 1 $[ 2*j ]` ; do echo -n " " let aa++ done for bb in `seq 1 $[ 2*n-2*j-1 ]` ; do echo -ne "\033[33m* \033[0m" let bb++ done echo " " let j++ done
8 安裝centos6.7,用centos6.8kernel升級?(使用rmp命令讓系統有兩個Linux內核)
解:解題思路
rpm可以升級內核文件,不過不建議直接升級內核文件,linux支持多內核并存,建議直接安裝內核文件,我們來嘗試一下多內核并存。
/etc/grub.conf #系統啟動菜單顯示,多個內核會有多個啟動選項
uname -r 查看系統內核版本
/boot/ 內核文件存放路徑
查看現有系統啟動菜單配置文件(2.6.32.642)
[root@centos68 etc]# cat /etc/grub.conf #查看啟動菜單中內核啟動菜單 # grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/sda2 # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS 6 (2.6.32-642.el6.x86_64) #開機啟動菜單顯示的啟動菜單的名稱 root (hd0,0) kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e rd_NO_LUKS rd_NO_LVM.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-642.el6.x86_64.img
查看現有系統版本(2.6.32.642)
[root@centos68 etc]# uname -r #查看系統版本 2.6.32-642.el6.x86_64
查看現有系統kernel文件(2.6.32.642)
[root@centos68 etc]# ll -h /boot/vmlinuz-2.6.32-642.el6.x86_64 -rwxr-xr-x. 1 root root 4.1M May 11 01:32 /boot/vmlinuz-2.6.32-642.el6.x86_64 [root@centos68 etc]#
在現有系統上正常安裝與升級都不允許安裝或升級版本低的內核文件
[root@centos68 ~]# rpm -ivh kernel-2.6.32-431.el6.x86_64.rpm Preparing... ########################################### [100%] package kernel-2.6.32-642.el6.x86_64 (which is newer than kernel-2.6.32-431.el6.x86_64) is already installed [root@centos68 ~]# [root@centos68 ~]# rpm -Uvh kernel-2.6.32-431.el6.x86_64.rpm Preparing... ########################################### [100%] package kernel-2.6.32-642.el6.x86_64 (which is newer than kernel-2.6.32-431.el6.x86_64) is already installed
強制升級后現有系統2.6.32.642 強制升級2.6.32-431
[root@centos68 ~]# rpm -Uvh --force kernel-2.6.32-431.el6.x86_64.rpm Preparing... ########################################### [100%] 1:kernel ########################################### [100%] warning: erase unlink of /lib/modules/2.6.32-642.el6.x86_64/weak-updates failed: No such file or directory warning: erase unlink of /lib/modules/2.6.32-642.el6.x86_64/modules.order failed: No such file or directory warning: erase unlink of /lib/modules/2.6.32-642.el6.x86_64/modules.networking failed: No such file or directory warning: erase unlink of /lib/modules/2.6.32-642.el6.x86_64/modules.modesetting failed: No such file or directory warning: erase unlink of /lib/modules/2.6.32-642.el6.x86_64/modules.drm failed: No such file or directory warning: erase unlink of /lib/modules/2.6.32-642.el6.x86_64/modules.block failed: No such file or directory [root@centos68 ~]#
強制使用2.6.32-431 升級后,查看系統的版本
強制升級后導致系統版本降低(2.6.32-431 ) [root@centos68 ~]# uname -r 2.6.32-431.el6.x86_64
強制升級后導致系統版本降低(2.6.32-431 )(啟動菜單中只有2.6.32-431的系統啟動菜單)
[root@centos68 ~]# cat /etc/grub.conf # grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/sda2 # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.32-431.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e rd_NO_LUKS rd_NO_LVM.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-431.el6.x86_64.img [root@centos68 ~]#
在2.6.32-431 系統上安裝2.6.32-642的內核后,查看系統的版本
[root@centos68 Packages]# rpm -ivh kernel-2.6.32-642.el6.x86_64.rpm Preparing... ########################################### [100%] 1:kernel ########################################### [100%]
查看系統啟動菜單(有兩個啟動菜單,兩個菜單都可以正常的啟動)
[root@centos68 ~]# cat /etc/grub.conf #查看到有兩個啟動菜單 # grub.conf generated by anaconda # # Note that you do not have to rerun grub after making changes to this file # NOTICE: You have a /boot partition. This means that # all kernel and initrd paths are relative to /boot/, eg. # root (hd0,0) # kernel /vmlinuz-version ro root=/dev/sda2 # initrd /initrd-[generic-]version.img #boot=/dev/sda default=0 timeout=5 splashimage=(hd0,0)/grub/splash.xpm.gz hiddenmenu title CentOS (2.6.32-642.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-642.el6.x86_64 ro root=UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e rd_NO_LUKS rd_NO_LVM.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-642.el6.x86_64.img title CentOS (2.6.32-431.el6.x86_64) root (hd0,0) kernel /vmlinuz-2.6.32-431.el6.x86_64 ro root=UUID=ca4c44c8-1c65-4896-a295-d55e5d5e5c5e rd_NO_LUKS rd_NO_LVM.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto KEYBOARDTYPE=pc KEYTABLE=us rd_NO_DM rhgb quiet initrd /initramfs-2.6.32-431.el6.x86_64.img [root@centos68 ~]# 小結: 1.低版本無法在高版本的系統上安裝與升級,強制安裝與升級也可以。 2.升級會覆蓋原來的文件系統中的啟動菜單。 3.安裝會在原來版本的linux系統在安裝一個linux內核,在配置文件中也會寫入相應的啟動菜單。 4.由于是同一版本的升級與安裝,雙內核系統可以正常運行,但是同時只能進入一個系統。至于兩個系統有區別和問題需要在后續的過程中測試。
原創文章,作者:linux_root,如若轉載,請注明出處:http://www.www58058.com/36784