本節內容
1. shell流程控制
2. for語句
3. while語句
4. break和continue語句
5. case語句
6. shell編程高級實戰
shell流程控制
流程控制是改變程序運行順序的指令。linux shell有一套自己的流程控制語句,其中包括條件語句(if),循環語句(for,while),選擇語句(case)。下面我將通過例子介紹下,各個語句使用方法
if語句
格式:
格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi
1.1 單分支
if 條件表達式; then
命令
fi
實例:
#!/bin/bash N=10 if [ $N -gt 5 ]; then echo yes fi # bash test.sh yes
1.2 雙分支
if 條件表達式; then 命令 else 命令 fi
實例1:
#!/bin/bash N=10 if [ $N -lt 5 ]; then echo yes else echo no fi # bash test.sh no
實例2:判斷crond進程是否正在運行
-v: 表示取反
-c: 即count,取代通常的輸出,顯示行數
#!/bin/bash NAME=crond NUM=$(ps aux | grep $NAME | grep -vc grep) if [ $NUM -eq 1 ]; then echo "$NAME running." else echo "$NAME is not running!" fi
實例3:檢查主機是否在線
-c:表示發送幾次包
-w:表示等待時間。當試圖檢測不可達主機時此選項很有用。
#!/bin/bash if ping -c 1 192.168.1.1 &>/dev/null; then
echo "OK." else echo "NO!" fi
if 語句可以直接對命令狀態進行判斷,就省去了獲取$?這一步!
1.3 多分支
if 條件表達式; then 命令 elif 條件表達式; then 命令 else 命令 fi
當不確定條件符合哪一個時,就可以把已知條件判斷寫出來,做相應的處理。
實例1:
$1:表示接受用戶輸入參數
#!/bin/bash N=$1 if [ $N -eq 3 ]; then echo "eq 3" elif [ $N -eq 5 ]; then echo "eq 5" elif [ $N -eq 8 ]; then echo "eq 8" else echo "no" fi
如果第一個條件符合就不再向下匹配。
shell編程之if語句實戰案例
需求:
1. 完成用戶輸入文件或者目錄的自動復制,並可以實現用戶指定復制目標位置。
2. 用戶體驗佳。
#!/bin/bash read -p "pls enter a file you want to copy:" file if [ -f $file -o -d $file ];then read -p "do you want to copy the $file?(y/n)" sure
confirm=$(echo ${sure} | tr A-Z a-z) if [ "$confirm" == "y" ];then read -p "where do you want to copy?" dire if [ -d $dire ];then cp -a $file $dire echo "the $file copied to $dire" else echo "the $dire is not exists" exit 1 fi elif [ "$confirm" == "n" ];then echo "bye" else echo "pls input y or n" fi else echo "the $file is not exists" fi
練習題1:嘗試寫一個shell簡單的計算器,實現加減乘除。
請輸入一個數字: 7
請輸入運算符:+
請輸入第二個數字:7
7+7=14
練習題2:輸入一個用戶,用腳本判斷判斷該用戶是否存在。
for語句
格式:for name [ [ in [ word ... ] ] ; ] do list ; done
for 變量名 in 取值列表; do 命令 done
或者
for 變量名 in 取值列表
do
命令
done
實例1:
#!/bin/bash for i in {1..3}; do echo $i done # bash test.sh 1 2 3
實例2:計算100以內偶數和
#!/bin/bash sum=0 for i in `seq 2 2 100` do let sum+=$i done echo "$sum"
shell編程之for語句實戰案例
需求:
1. 批量檢查當前教室主機是否在線
#!/bin/bash . /etc/init.d/functions ip=192.168.7. for i in {100..150} do if ping -c 1 -w 1 $ip$i &>/dev/null;then echo -n "$ip$i在線!" success echo "" else echo -n "$ip$i不在線!" failure echo "" fi done
練習題1:計算100以內的奇數和
練習題2:判斷/root目錄下面的文件類型
while語句
條件為真就進入死循環;條件為假就退出循環
格式:while list; do list; done
while 條件表達式; do 命令 done
實例1:
#!/bin/bash N=0 while [ $N -lt 5 ]; do let N++ echo $N done # bash test.sh 1 2 3 4 5
當條件表達式為 false 時,終止循環。
實例2:條件表達式為 true,將會產生死循環
#!/bin/bash while [ 1 -eq 1 ]; do echo "yes" done
也可以條件表達式直接用 true:
#!/bin/bash while true; do echo "yes" done
死循環有什么作用那?
可以用來后台運行檢測腳本,如下是是一個檢測腦裂的腳本
我們只需要在命令行中輸入 nohup bash naolie.sh & 即可在后台持續運行該腳本
例子1:檢測腦裂
#!/bin/bash while true do ip=`ip a s eth0 | awk -F " +" 'NR==4{print $3}' | awk -F "/" '{print $1}' | awk -F "." '{print $4}'`1 ping -c 3 -i 1 -W 1 10.220.5.166 &>/dev/null if [ $? -eq 0 ] && [ $ip = 1001 ];then echo "happed naolie" else echo "everything is ok" fi done
例子2:檢測終端數量
#!/bin/bash while true do num=`who | wc -l` echo "當前打開終端數量為:$num" sleep 5 done
要想使用 while 循環逐行讀取 a.txt 文件,有三種方式:
方式 1:
#!/bin/bash cat ./a.txt | while read LINE; do echo $LINE done
方式2:
#!/bin/bash while read LINE; do echo $LINE done < ./a.txt
方式3:
exec < ./a.txt # 讀取文件作為標准輸出 while read LINE; do echo $LINE done
與 while 關聯的還有一個 until 語句,它與 while 不同之處在於,是當條件表達式為 false 時才循環,實際使用中比較少,這里不再講解。
#!/bin/bash n=0 until [ $n -eq 5 ] do let n++ echo "$n" done
break和continue語句
break 是終止循環。
continue 是跳出當前循環。
示例 1:在死循環中,滿足條件終止循環
#!/bin/bash N=0 while true; do let N++ if [ $N -eq 5 ]; then break fi echo $N done # bash test.sh 1 2 3 4
里面用了 if 判斷,並用了 break 語句,它是跳出循環。與其關聯的還有一個 continue 語句,它是跳出本次循環。
示例 2:舉例子說明 continue 用法
#!/bin/bash N=0 while [ $N -lt 5 ]; do let N++ if [ $N -eq 3 ]; then continue fi echo $N done # bash test.sh 1 2 4
當變量 N 等於 3 時,continue 跳過了本次循環,沒有執行下面的 echo。
注意:continue 與 break 語句只能循環語句中使用。
[root@ken-node1 ~]# cat test.sh #!/bin/bash st=0 while true do let st++ if [ $st -eq 5 ];then continue elif [ $st -eq 10 ];then break else echo "$st" fi done [root@ken-node1 ~]# bash test.sh 1 2 3 4 6 7 8 9
case語句
case 語句一般用於選擇性來執行對應部分塊命令。
case 模式名 in 模式 1) 命令 ;; 模式 2) 命令 ;; *) 不符合以上模式執行的命令 esac
每個模式必須以右括號結束,命令結尾以雙分號結束,最后一個模式不需要添加;;。
示例1:根據位置參數匹配不同的模式
#!/bin/bash case $1 in start) echo "start." ;; stop) echo "stop." ;; restart) echo "restart." ;; *) echo "Usage: $0 {start|stop|restart}" esac # bash test.sh Usage: test.sh {start|stop|restart} # bash test.sh start start. # bash test.sh stop stop. # bash test.sh restart restart.
實例2:
#!/bin/bash case $1 in [0-9]) echo "match number." ;; [a-z]) echo "match letter." ;; '-h'|'--help') echo "help" ;; *) echo "Input error!" exit esac # bash test.sh 1 match number. # bash test.sh a match letter. # bash test.sh -h help # bash test.sh --help help
模式支持的正則有:*、?、[ ]、[.-.]、|。后面有章節單獨講解 Shell 正則表達式。
shell編程高級實戰
實戰1:寫一個猜數字的小游戲
要求:
1. 猜對退出
2. 數字隨機
3. 使用體驗佳
#!/bin/bash clear num=`echo $RANDOM` count=0 while true do let count++ read -p "pls enter a num you guess:" guessnum if [ $guessnum -lt $num ]; then echo "the num is so smaller!" elif [ $guessnum -gt $num ];then echo "the num is so bigger!" elif [ $guessnum -eq $num ];then echo "right!wonderful! " break else echo "good bye" exit fi done echo -e "\033[36myou guess $count times\033[0m" #-e允許對下面列出的加反斜線轉義的字符進行解釋.
實戰2:檢測當前教室在線IP地址
要求:
1.顯示美觀
#!/bin/bash . /etc/init.d/functions ip=172.20.10. for i in {1..255} do if ping -c 1 $ip$i &>/dev/null ;then echo -n "$ip$i" #-n表示不輸出行尾的換行符 success echo "" else echo -n "$ip$i" failure echo "" fi done
實戰3:檢查軟件包是否安裝
要求:
1.用戶輸入軟件名即可進行查詢
#!/bin/bash read -p "pls enter a softname:" softname if rpm -q $softname &>/dev/null ;then echo "the $softname is already installed" else echo "the $softname" is not installed fi
實戰4:打印九九乘法表
#!/bin/bash for i in `seq 9` do for a in `seq 9` do if [ $a -le $i ];then echo -n "$a*$i=$(($i*$a)) " fi done echo "" done
補充練習題
1.實現簡單計算器(加減乘除)
#!/bin/bash read -p "請輸入第一個數字:" a read -p "請輸入運算符[+-*/]:" b read -p "請輸入第二個數字:" c if [ -n "$a" -a -n "$b" -a -n "$c" ];then if [ "$b" == "+" ];then echo "$a+$c=$(($a+$c))" elif [ "$b" == "-" ];then echo "$a-$c=$(($a-$c))" elif [ "$b" == "*" ];then echo "$a*$c=$(($a*$c))" elif [ "$b" == "/" ];then echo "$a/$c=$(($a/$c))" else echo "請輸入+—*%" fi else echo "請按照要求輸入內容!" fi
2. 批量創建100個以數字開頭的文件,並每隔一秒鍾輸出到終端
#!/bin/bash for i in {1..100} do touch ${i}.txt echo "${i}.txt" sleep 1 done
3.動態持續監測本機linux系統內存剩余量(僅顯示數值),並在終端輸出
#!/bin/bash while true do mem=`free -h | grep "Mem" | cut -d "M" -f 4 | tr -d " "` echo $mem sleep 1 done
課后練習題
寫一個腳本: 實現自動化一鍵部署NFS服務器端和客戶端
第二個腳本:實現批量化檢測當前教室主機在線狀況,在線主機保存至一個文件中
第三個腳本:實現批量化創建100個用戶,並創建8位隨機密碼,且可登陸
第四個腳本:找出系統中含有某個關鍵詞的文件,並輸出到終端,關鍵詞用戶輸入指定
第五個腳本:批量判斷當前目錄下所有文件類型
補充:shell練習題
1. 每一秒鍾輸出/root下的文件至屏幕
2. 打印出包含某個關鍵詞的文件(關鍵詞執行腳本時接收)
3. 統計系統中以.sh結尾的文件總大小,輸出結果以kb為單位
參考答案:
1.
#!/bin/bash
for file in `ls /root` do echo $file sleep 1 done
2.
#!/bin/bash
key=$1
for file in `find / -type f` do grep "$key" $file &>/dev/null if [ $? -eq 0 ];then echo $file sleep 1 fi done
3.
#!/bin/bash
sum=0
for size in `find /root -name "*.sh" -exec ls -l {} \; | cut -d " " -f 5` do let sum+=$size done echo "$((sum/1024))kb"