1. 程式人生 > >shell腳本應用(三)for、while、case語句

shell腳本應用(三)for、while、case語句

姓名 std proc pgrep 符號 prefix dfa 先生 let

前言:當面對各種列表重復任務時,使用if語句已經難以滿足要求,而順序編寫全部代碼更是顯得異常繁瑣,困難重重。使用循環、分支等其他程序控制結構,從而能夠輕松完成更加復雜、強大的功能。
1、使用for循環語句
for語句結構:
for 變量名 in 取值列表
do
命令序列
done
for循環語句的結構:
技術分享圖片
1)根據姓名列表批量添加用戶
準備員工列表文件users.txt,然後編寫一個名為uaddfor.sh的腳本,從users.txt文件中讀取各用戶名稱,重復執行添加用戶,設置初始密碼的相關操作。
[root@localhost ~]# vim /root/user.txt //用作測試的列表文件
chenpeng
dengchao
zhangjie
批量添加用戶的腳本
[root@localhost ~]# vim uaddfor.sh
#!/bin/bash
ulist=$(cat /root/user.txt)
for uname in $ulist
do
useradd $uname
echo "123456" | passwd --stdin $uname &> /dev/null
done
[root@localhost ~]# chmod +x uaddfor.sh //添加執行權限
[root@localhost ~]# ./uaddfor.sh //測試並確認執行結果
[root@localhost ~]# tail -3 /etc/passwd
chenpeng:x:501:501::/home/chenpeng:/bin/bash
dengchao:x:502:502::/home/dengchao:/bin/bash
zhangjie:x:503:503::/home/zhangjie:/bin/bash
2)若要刪除uaddfor.sh腳本添加的用戶,只需要將上面腳本中添加用戶的命令改為刪除的即可。
[root@localhost ~]# cp uaddfor.sh udelfor.sh
[root@localhost ~]# vim udelfor.sh //批量刪除用戶的腳本
#!/bin/bash
ulist=$(cat /root/user.txt)
for uname in $ulist
do
userdel $uname
echo "123456" | passwd --stdin $uname &> /dev/null
done
[root@localhost ~]# chmod +x udelfor.sh
[root@localhost ~]# ./udelfor.sh
[root@localhost ~]# id chenpeng
id: chenpeng:無此用戶
執行腳本之後發現用戶已經刪除
3)根據ip地址列表查看主機狀態
首先建立ip地址列表文件ipadds.txt,然後編寫一個名為chkhosts.sh的shell腳本,從ipadds.txt文件中讀取各服務器的ip地址,重復執行ping連通性測試,並根據測試結果輸出相應的提示信息。
[root@localhost ~]# vim /root/ipadds.txt //用作測試的列表文件
192.168.1.1
192.168.1.2
192.168.1.10
[root@localhost ~]# vim /chkhosts.sh //循環檢查各主機的腳本
#!/bin/bash
hlist=$(cat /root/ipadds.txt)
for ip in $hlist
do
ping -c 3 -i 0.2 -W 3 $ip &> /dev/null
if [ $? -eq 0 ]
then
echo "host $ip is up"
else
echo "host $ip is down"
fi
done
執行腳本
[root@localhost /]# chmod +x chkhosts.sh
[root@localhost /]# ./chkhosts.sh
host 192.168.1.1 is up
host 192.168.1.2 is down
host 192.168.1.10 is down
2、使用while循環語句
For循環適合無規律,列表已固定,while循環適合要求循環次數,操作對象按數字順序編號,按特定條件執行重復操作的情況。
while語句的語法結構:
while 條件測試操作
do
命令序列
done
while循環語句的結構:
技術分享圖片
1)批量添加規律編號的用戶,添加20個用戶,名稱依次為stu1,stu2,... Stu20
[root@localhost /]# vim uaddwhile.sh
#!/bin/bash
prefix="stu"
i=1
while [ $i -le 20 ]
do
useradd ${prefix}$i
echo "123456" | passwd --stdin ${prefix}$i &> /dev/null
let i++
done
[root@localhost /]# chmod +x uaddwhile.sh
[root@localhost /]# ./uaddwhile.sh
[root@localhost /]# grep "stu" /etc/passwd | tail -3
stu18:x:518:518::/home/stu18:/bin/bash
stu19:x:519:519::/home/stu19:/bin/bash
stu20:x:520:520::/home/stu20:/bin/bash
2)刪除所添加的用戶,只需將上述代碼useradd修改成userdel即可
[root@localhost /]# cp uaddwhile.sh udelwhile.sh
[root@localhost /]# vim udelwhile.sh
#!/bin/bash
prefix="stu"
i=1
while [ $i -le 20 ]
do
userdel ${prefix}$i
echo "123456" | passwd --stdin ${prefix}$i &> /dev/null
let i++
done
[root@localhost /]# chmod +x udelwhile.sh
[root@localhost /]# ./udelwhile.sh
[root@localhost /]# id stu20
id: stu20:無此用戶
3)猜價格遊戲
案例要求如下:由腳本預先生成一個隨機的價格數目(0~999)作為實際價格,判斷用戶猜測的價格是否高出或低出實際價格,給出相應的提示夠再次要求用戶猜測;一直到用戶猜中實際價格為止,輸出用戶共猜測的次數、實際價格。
思路:通過環境變量RANDOM可獲得一個小於2的16次方的隨機整數,計算其與1000的余數即可獲得0-999的隨機價格,反復猜測操作可以通過以true作為測試條件的while循環實現,當用戶猜中實際價格時終止循環,判斷猜測價格與實際價格的過程采用if語句實現,嵌套在while循環體內,使用變量來記錄猜測次數。
[root@localhost /]# vim pricegame.sh
#!/bin/bash
price=$(expr $RANDOM % 1000)
TIMES=0
echo "shangpin 0-999,ni cai?"
while true
do
read -p "qing shu ru:" INT
let TIMES++
if [ $INT -eq $price ] ; then
echo "gongxi, jiageshi:$price"
echo "ni cai le $TIMES ci"
exit 0
elif [ $INT -gt $price ] ; then
echo "taigaole"
else
echo "taidile"
fi
done
[root@localhost /]# chmod +x pricegame.sh
[root@localhost /]# ./pricegame.sh
shangpin 0-999,ni cai?
qing shu ru:500
taigaole
qing shu ru:400
taidile
qing shu ru:450
taidile
qing shu ru:470
taigaole
qing shu ru:469
taigaole
qing shu ru:460
gongxi, jiageshi:460
ni cai le 6 ci
3、使用case分支語句
Case語句可以使用腳本程序的結構更加清晰。與if語句非常相似,只不過if語句需要判斷多個不同的條件,而case語句只是判斷一個變量的不同取值。
case分支語句的語法結構:
case 變量值 in
模式1)
命令序列1
;;
模式2)
命令序列2
;;
......................

默認命令序列
esac
(
是通配符,可匹配任意值)
case分支語句的結構:
技術分享圖片
使用case分支語句時,需要註意:
1,case行尾必須為單詞“in”,每一模式必須以右括號“)”結束
2,雙分號“;;”表示命令序列的結束
3,模式字符串中,可以用方括號表示一個連續的範圍,如【0-9】;還可以用豎杠符號“|”表示或,如“A|B”
4,最後的“)”表示默認模式,其中的相當於通配符
1)檢查用戶輸入一個字符,通過case語句判斷該字符是否為字母,數組或其他控制字符,並給出相應的提示信息。
[root@localhost /]# vim hitkey.sh
#!/bin/bash
read -p "qingshuru:" KEY
case "$KEY" in
[a-z] | [A-Z])
echo "ni shu ru de shi zimu"
;;
[0-9])
echo "ni shu ru de shi shuzi"
;;
)
echo "ni shu ru de shi qita"
esac
[root@localhost /]# chmod +x hitkey.sh
[root@localhost /]# ./hitkey.sh
qingshuru:z
ni shu ru de shi zimu
[root@localhost /]# ./hitkey.sh
qingshuru:7
ni shu ru de shi shuzi
[root@localhost /]# ./hitkey.sh
qingshuru: /
ni shu ru de shi qita
2)編寫系統服務腳本
通過位置變量$1指定的start,stop,restart,status控制參數,分別用來啟動、停止、重啟sleep進程,以及查看sleep進程的狀態。
[root@localhost /]# vim myprog
#!/bin/bash
#chkconfig - 90 10
#description:aaaaaaaaaa
case "$1" in
start)
echo -n "zhengzaiqidong sleep fuwu..."
if sleep 7200 & //在後臺啟動sleep進程
then
echo "ok"
fi
;;
stop)
echo -n "zhengzaitingzhi sleep fuwu"
pkill "sleep" &> /dev/null //殺死sleep進程
echo "ok"
;;
status)
if pgrep "sleep" &> /dev/null ; then //判斷並提示sleep進程狀態
echo "sleep fuwu yiqidong"
else
echo "sleep fuwu yitingzhi"
fi
;;
restart) //先停止,再啟動服務
$0 stop
$0 start
;;
) //默認顯示用法信息
echo "yongfa: $0 {start|stop|status|restart}"
esac
[root@localhost /]# chmod +x myprog
[root@localhost /]# ./myprog start
zhengzaiqidong sleep fuwu...ok
[root@localhost /]# ./myprog status
sleep fuwu yiqidong
[root@localhost /]# ./myprog stop
zhengzaitingzhi sleep fuwuok
[root@localhost /]# ./myprog reload //未提供此參數,按默認處理
yongfa: ./myprog {start|stop|status|restart}

然後執行下面的命令添加myprog為系統服務
[root@localhost /]# cp myprog /etc/init.d/
技術分享圖片

shell腳本應用(三)for、while、case語句