循環(huán)語(yǔ)句常用于重復(fù)執(zhí)行一條指令或一組指令萧诫,直到條件不滿足停止,shell腳本語(yǔ)言的循環(huán)語(yǔ)句常見的有while枝嘶、until财搁、for、select循環(huán)語(yǔ)句躬络,其中,until和select已經(jīng)基本淡出歷史舞臺(tái)搭儒。本章講while循環(huán)
while循環(huán)語(yǔ)句主要用來(lái)重復(fù)執(zhí)行一組命令會(huì)語(yǔ)句穷当。在企業(yè)中常用于守護(hù)進(jìn)程或持續(xù)運(yùn)行的程序,特別是一些監(jiān)控任務(wù)淹禾。也有時(shí)候會(huì)用while來(lái)讀取文件的每一行內(nèi)容
1馁菜、while語(yǔ)法
while循環(huán)的基本語(yǔ)法為:
while <條件表達(dá)式>
do
指令
done
或
while <條件表達(dá)式>;do
指令
done
while循環(huán)會(huì)對(duì)緊跟在while后的條件表達(dá)式判斷,如果條件成立铃岔,就執(zhí)行while里面的命令或語(yǔ)句汪疮,每次執(zhí)行到done時(shí)候就重新判斷while表達(dá)式是否真的成立,直到表達(dá)式不成立才退出while循環(huán)體毁习,如果一開始就不成立智嚷,就不會(huì)進(jìn)入循環(huán)體。
2纺且、while循環(huán)執(zhí)行的流程圖如下所示:
3盏道、while按行讀入文件
while可以讀取指定的文件,然后可以對(duì)每行數(shù)據(jù)進(jìn)行自定義處理载碌,一共有三種方式:
3.1 exec方式猜嘱,僅供了解
exec < file
sum=0
while read line
do
echo $line
done
3.2 cat方式
cat file | while read line
do
echo $line
done
3.3 <重定向輸入方式(推薦使用的方式)
while read line
do
echo $line
done < file
4衅枫、while練習(xí):
4.1 while循環(huán)從1加到100,然后再額外使用兩種方式計(jì)算
方法1:echo "(1+100)*100/2"|bc
方法2:寫腳本
9 i=0
10 sum=0
11 while [ $i -lt 100 ];do
12 let i++
13 let sum=${sum}+$i
14 done
15 echo $sum
4.2 while循環(huán)讀入數(shù)據(jù)朗伶,計(jì)算文件內(nèi)的年齡平均值
[root@shelledu /server/scripts]# cat /server/txt/age.txt
jiaojiao 20
yingqian 20
jiangyuan 25
xiaolu 30
xuxu 18
dingsheng 38
lili 5
[root@shelledu /server/scripts]#
[root@shelledu /server/scripts]# cat while-test02.sh
#!/bin/bash
#while循環(huán)讀入數(shù)據(jù)弦撩,計(jì)算文件內(nèi)的年齡平均值
num=0
sum=0
while read line
do
let num++
age=`echo $line|awk '{print $2}'`
let sum=${sum}+${age}
done < /server/txt/age.txt
echo "共有 $num 人"
echo "年齡總共: $sum "
echo "年齡平均值: `echo ${sum}/${num}|bc`"
[root@shelledu /server/scripts]#
[root@shelledu /server/scripts]# sh while-test02.sh
共有 7 人
年齡總共: 156
年齡平均值: 22
[root@shelledu /server/scripts]#
4.3 將” 打印菜單,按照選擇項(xiàng)一鍵安裝不同的web服務(wù)”腳本,改為死循環(huán)的形式论皆。菜單中加入選項(xiàng)exit益楼,只有輸入exit才能退出
[root@shell-project /server/scripts]# cat while-home01.sh
#!/bin/bash
# 將” 打印菜單,按照選擇項(xiàng)一鍵安裝不同的web服務(wù)”腳本,將其中的條件表達(dá)式修改成case或if語(yǔ)句
#定義變量
lamp="/server/scripts/lamp.sh"
lnmp="/server/scripts/lnmp.sh"
while true
do
sleep 2
clear
#打印菜單
cat << EOF
1.[install lamp]
2.[install lnmp]
3.[exit]
EOF
#使用read讀取輸入
read -p 'please input the num you want: ' num
#定義函數(shù)
function lamp_lanp(){
if [ -f "$1" ];then
if [ ! -x "$1" ];then
echo "$1 沒有執(zhí)行權(quán)限,不可執(zhí)行"
exit 2
else
$1
fi
else
echo "error: $1 is not exist."
exit 3
fi
}
case "$num" in
"1")
echo 'start installing lamp……'
lamp_lanp $lamp
;;
"2")
echo 'start installing lnmp……'
lamp_lanp $lnmp
;;
"3")
echo 'good byb!'
exit
;;
*)
echo 'Input Error. Please enter again.'
esac
done
[root@shell-project /server/scripts]#
5纯丸、案例實(shí)操
5.1 猜數(shù)字游戲:首先讓系統(tǒng)隨機(jī)生成一個(gè)數(shù)字偏形,給這個(gè)數(shù)字定一個(gè)范圍(1-100),讓用戶輸入猜的數(shù)字觉鼻,對(duì)輸入的數(shù)字進(jìn)行判斷俊扭,如果不符合要求,就給與高或低的提示坠陈,猜對(duì)后給出猜對(duì)用的次數(shù)萨惑,請(qǐng)用while語(yǔ)句實(shí)現(xiàn)
[root@shell-project /server/scripts]# cat while-home-caiziyouxi.sh
#!/bin/bash
#猜數(shù)字游戲:首先讓系統(tǒng)隨機(jī)生成一個(gè)數(shù)字,給這個(gè)數(shù)字定一個(gè)范圍仇矾,讓用戶輸入猜的數(shù)字庸蔼,對(duì)輸入的數(shù)字進(jìn)行判斷,如果不符合要求,就給與高或低的提示,猜對(duì)后給出猜對(duì)用的次數(shù)氢拥,請(qǐng)用while語(yǔ)句實(shí)現(xiàn)噪珊。
#定義變量
count=0
rnd=$(($RANDOM%100+1))
echo -e "\E[1;31m=============歡迎進(jìn)入猜數(shù)字游戲============== \E[0m"
while true;do
read -p "請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: " num
let count++
expr $num + 1 >/dev/null 2>&1
if [ $? -gt 0 ];then
echo "輸入錯(cuò)誤,請(qǐng)看清楚提示!!"
else
if [ $num -gt 100 -o $num -le 0 ];then
echo "數(shù)字范圍在1-100之間,請(qǐng)重新輸入!"
else
if [ $num -gt $rnd ];then
echo "猜的數(shù)字大了!!"
elif [ $num -lt $rnd ];then
echo "猜的數(shù)字小了B睢!"
else
echo -e "\E[1;31m恭喜你乙墙,猜對(duì)了S北洹!您猜對(duì)共用 $count 次. \E[0m"
exit
fi
fi
fi
done
[root@shell-project /server/scripts]#
[root@shell-project /server/scripts]# sh while-home-caiziyouxi.sh
=============歡迎進(jìn)入猜數(shù)字游戲==============
請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: 50
猜的數(shù)字小了L搿腥刹!
請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: 70
猜的數(shù)字小了!汉买!
請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: 80
猜的數(shù)字大了8刈摺!
請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: 75
猜的數(shù)字大了!朽色!
請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: 73
猜的數(shù)字大了A谕獭!
請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: 72
猜的數(shù)字大了:小抱冷!
請(qǐng)您輸入你要猜的數(shù)字,范圍1-100: 71
恭喜你,猜對(duì)了I液帧旺遮!您猜對(duì)共用 7 次.
[root@shell-project /server/scripts]#
5.2 使用if和while實(shí)現(xiàn)菜單系統(tǒng)信息案例:
h 顯示命令幫助
f 顯示登錄信息
d 顯示磁盤掛載
m 查看內(nèi)存使用
u 查看系統(tǒng)負(fù)載
q 退出程序
[root@shell-project /server/scripts]# cat while-home-caidan.sh
#!/bin/bash
#使用if和while實(shí)現(xiàn)菜單系統(tǒng)信息案例
#定義函數(shù)
function print_info(){
cat <<EOF
h: [顯示命令幫助]
f: [顯示登錄信息]
d: [顯示磁盤掛載]
m: [查看內(nèi)存使用]
u: [查看系統(tǒng)負(fù)載]
q: [退出程序]
EOF
}
print_info
while true;do
read -p "請(qǐng)輸入要查詢的內(nèi)容: " cm
case "$cm" in
"h")
print_info
;;
"f")
who
;;
"d")
fdisk -l
;;
"m")
free -h
;;
"u")
w
;;
"q")
echo 'exit'
exit
;;
*)
echo "參數(shù)錯(cuò)誤,請(qǐng)重新輸入"
esac
done
[root@shell-project /server/scripts]#
5.3 while循環(huán)案例盈咳,可以批量創(chuàng)建10個(gè)用戶耿眉,并通過傳參方式傳入密碼123
創(chuàng)建用戶: useradd test1
添加密碼:
echo 123 | passwd --stdin test1
批量創(chuàng)建
seq 1 10
[root@shell-project /server/scripts]# cat while-home-adduser.sh
#!/bin/bash
#可以批量創(chuàng)建10個(gè)用戶,并通過傳參方式傳入密碼123
read -p "請(qǐng)輸入用戶名的前綴: " qian
read -p "請(qǐng)輸入要?jiǎng)?chuàng)建用戶的個(gè)數(shù): " num
expr $num + 1 >/dev/null 2>&1
if [ $? -gt 0 ];then
echo '用戶個(gè)數(shù)請(qǐng)輸入正整數(shù)!'
exit
fi
read -p "請(qǐng)輸入要?jiǎng)?chuàng)建用戶的密碼: " psd
if [ -n "$(echo "$psd" | sed 's#[0-9a-z]##g')" ];then
echo '密碼只能輸入數(shù)字和小寫字母!'
exit
fi
i=1
while [ $i -le $num ];do
echo ${qian}$i
name=${qian}$i
let i++
id $name >/dev/null 2>&1
if [ $? -eq 0 ];then
echo "$name 用戶已經(jīng)存在鱼响,創(chuàng)建失敗."
continue
else
useradd $name
echo "$psd"|passwd --stdin "$name"
echo "$name 用戶創(chuàng)建成功."
fi
done
[root@shell-project /server/scripts]#
5.4 使用case和while循環(huán)批量刪除用戶[y|n]
[root@shell-project /server/scripts]# cat while-home-deluser.sh
#!/bin/bash
# 使用case和while循環(huán)批量刪除用戶[y|n]
while true;do
read -p "請(qǐng)輸入要?jiǎng)h除的用戶名: " name
if [ -z $name ];then
echo "對(duì)不起鸣剪,請(qǐng)輸入用戶名,否則不能刪除丈积!"
elif [ $(grep "${name}:" /etc/passwd|wc -l) -eq 0 ];then
echo "對(duì)不起筐骇,要?jiǎng)h除的用戶不存在!"
else
while true;do
read -p "請(qǐng)確認(rèn)是否刪除["$name"] [y|n]? " sel
case "$sel" in
"y")
userdel $name
read -p "[$name]用戶刪除成功,是否繼續(xù) [yes|no]? " qus
if [ "$qus" = "yes" ];then
continue 2
fi
if [ "$qus" = "no" ];then
echo 'exit'
exit
fi
;;
"n")
echo 'exit'
exit
;;
*)
echo '輸入錯(cuò)誤江滨,請(qǐng)重新確認(rèn). '
esac
done
fi
done
[root@shell-project /server/scripts]#
5.5 while循環(huán)通過文本來(lái)直接創(chuàng)建用戶和密碼铛纬,如果用戶存在或者創(chuàng)建失敗給予提示
[root@shell-project /server/scripts]# cat /server/txt/user.txt
xiaohong 123456
wanghua 123456
lisisi 123456
xiaokeai 123456
yangguang 123456
[root@shell-project /server/scripts]#
[root@shell-project /server/scripts]# cat while-home-adduserbytxt.sh
#!/bin/bash
#while循環(huán)通過文本來(lái)直接創(chuàng)建用戶和密碼,如果用戶存在或者創(chuàng)建失敗給予提示
#定義變量
while read line
do
name=$(echo "$line"|awk '{print $1}')
mima=$(echo "$line"|awk '{print $2}')
if [ $(grep "${name}:" /etc/passwd|wc -l) -gt 0 ];then
echo "$name 用戶已經(jīng)存在."
else
useradd "$name" >/dev/null 2>&1
if [ $? -gt 0 ];then
echo "$name 用戶創(chuàng)建失敗."
else
echo "$name 用戶創(chuàng)建成功."
#修改密碼
echo "$mima"|passwd --stdin "$name" >/dev/null 2>&1
if [ $? -eq 0 ];then
echo "$name 用戶密碼修改成功."
else
echo "$name 用戶密碼修改失敗."
fi
fi
fi
done < /server/txt/user.txt
[root@shell-project /server/scripts]#