Shell流程语句
1. shell流程控制
流程控制是改變程序運行順序的指令。linux shell有一套自己的流程控制語句,其中包括條件語句(if),循環語句(for,while),選擇語句(case)。
2. if語句
格式:if list; then list; [ elif list; then list; ] ... [ else list; ] fi
2.1 ?單分支
if 條件表達式; then
命令
fi
[root@localhost ~]# vim test.sh #!/bin/bash if [ 1 -eq 1 ];thenecho "yes" fi [root@localhost ~]# bash test.sh yes?
2.2 雙分支?
if 條件表達式; then
命令
else
命令
fi
#!/bin/bash if [ 1 -eq 2 ];thenecho "yes" elseecho "no" fi [root@localhost ~]# bash -x test.sh #-x,調試 + '[' 1 -eq 2 ']' + echo no no #判斷crond進程是否正在運行 [root@localhost ~]# ps aux | grep "grep" root 11941 0.0 0.0 112648 956 pts/3 S+ 20:30 0:00 grep --color=auto [root@localhost ~]#vim cron_d.sh #!/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 #檢查主機是否在線 #!/bin/bash if ping -c 1 192.168.1.1 &>/dev/null; then #if可以直接對命令進行判斷 echo "OK." else echo "NO!" fi?
2.3 多分支
if 條件表達式; then
命令
elif 條件表達式; then
命令
else
命令
fi
#!/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
如果第一個條件符合就不再向下匹配。
在寫腳本時先在命令測試,無誤后再寫入腳本
?
if語句實例:編寫一個計算器,實現簡單的加減乘除
要求:
請輸入一個數字: 7
請輸入運算符:+
請輸入第二個數字:7
7+7=14
[root@localhost ~]# vim count.sh #!/bin/bash read -p "請輸入第一個數字:" num1 read -p "請輸入運算符:" cha read -p "請輸入第二個數字:" num2 count (){echo "${num1}${cha}${num2}=$((${num1}${cha}${num2}))" } error () {echo "Usage:$0 {+|-|*|/|0-9}" } if [ -n '$num1' -a -n '$hca' -a -n '$num2' ];thenif [ "$cha" == "+" ];thencountelif [ "$cha" == "-" ];thencountelif [ "$cha" == "*" ];thencountelif [ "$cha" == "/" ];thencountelseerrorfi elseecho '輸入內容不能為空' fi :wq [root@localhost ~]# bash count.sh 請輸入第一個數字:8 請輸入運算符:+ 請輸入第二個數字:2 8+2=10 [root@localhost ~]# bash count.sh 請輸入第一個數字:8 請輸入運算符:* 請輸入第二個數字:10 8*10=80 [root@localhost ~]# bash count.sh 請輸入第一個數字:l 請輸入運算符:l 請輸入第二個數字:l Usage:count.sh {+|-|*|/|0-9}?
?
3. for 語句
用于批量化部署
格式:for name [ [ in [ word ... ] ] ; ] do list ; done
for 變量名 in 取值列表; do
命令
done
或者
? for 變量名 in 取值列表
? do
命令
? done
?
[root@localhost ~]# vim for_test.sh #!/bin/bash for i in {1..5} doecho $isleep 1 #沉睡1秒,即1秒打印一個 done :wq [root@localhost ~]# bash for_test.sh 1 2 3 4 5 #實現100以內的偶數/奇數和[root@localhost ~]#vim count_ou.sh #!/bin/bash sum=0 for i in `seq 0 2 100` #偶數和 dolet sum+=$i done echo $sum :wq [root@localhost ~]# bash count_ou.sh 2550[root@localhost ~]# vim count_ji.sh #!/bin/bash sum=0 for i in `seq 1 2 100` #奇數和 dolet sum+=$i done echo $sum :wq [root@localhost ~]# bash count_ji.sh 2500
?
#批量檢查當前教室192.168.16.(1-10)網段主機是否在線 [root@localhost ~]# vim check_ip.sh #!/bin/bash . /etc/init.d/functions #引用文件 ip=192.168.16. for i in {1..10} doif ping -c 1 -w 1 $ip$i &>/dev/null;then #返回執行結果0或1,其他文件導入黑洞文件echo -n "$ip$i" #-n,不換行success #相應function函數echo "" #輸出空格elseecho -n "$ip$i"failureecho “ ”fi done [root@localhost ~]# bash check_ip.sh 192.168.16.1 [ OK ] 192.168.16.2 [ OK ] 192.168.16.3 [FAILED] 192.168.16.4 [FAILED] 192.168.16.5 [FAILED] 192.168.16.6 [FAILED] 192.168.16.7 [FAILED] 192.168.16.8 [FAILED] 192.168.16.9 [FAILED] 192.168.16.10 [FAILED]?
4. while語句用于監控
條件為真就進入死循環;條件為假就退出循環
格式:while list; do list; done
while 條件表達式; do
??? 命令
done
[root@localhost ~]# vim while_.sh #!/bin/bash n=0 while [ $n -lt 5 ] doecho "$n"let n++ done :wq [root@localhost ~]# bash while_.sh 0 1 2 3 4當條件表達式為 false 時,終止循環。
條件表達式為 true,將會產生死循環。
死循環有什么作用那?
可以用來后臺運行檢測腳本,如下是是一個檢測腦裂的腳本
我們只需要在命令行中輸入 nohup bash naolie.sh & 即可在后臺持續運行該腳本
#檢測終端數量 [root@localhost ~]# vim check_zh.sh= #!/bin/bash while true donum=`who | wc -l`echo"當前終端數量為$num"sleep 1 done :wq [root@localhost ~]# bash check_zh.sh 當前終端數量為5 當前終端數量為5 當前終端數量為6 當前終端數量為6 ^C#關掉該終端后停止檢測 #將檢測文件寫入文件并放在后臺執行 [root@localhost ~]# vim check_zh.sh #!/bin/bash while true donum=`who | wc -l`echo "當前終端數量為$num" >> /root/check_zhsleep 1 done :wq [root@localhost ~]# bash check_zh.sh & #&表示放在后臺 [1] 12336 [root@localhost ~]# tail -f check_zh 當前終端數量為3 當前終端數量為3 …..
#關閉寫入檢測文件的該終端,監測終端停止 #若想關閉終端繼續檢測,將該監測文件掛起 [root@localhost ~]# nohup bash check_zh.sh & [1] 16949 [root@localhost ~]# nohup: ignoring input and appending output to ‘nohup.out’[root@localhost ~]# ls nohup.out #生成nohup.out文件 在監測則在該終端關閉后無影響 [root@localhost ~]# tail -f check_zh 當前終端數量為3 當前終端數量為3 當前終端數量為2 當前終端數量為2 …….
#若要關掉該監測2關掉運行的進程即可 [root@localhost ~]# ps aux | grep check_zh root 13519 0.0 0.1 113124 1448 ? S 22:19 0:00 bash check_zh.sh root 16949 0.0 0.1 113124 1432 pts/0 S 22:28 0:00 bash check_zh.sh root 18476 0.0 0.0 112648 960 pts/0 R+ 22:31 0:00 grep --color=auto check_zh [root@localhost ~]# kill -9 13519 [root@localhost ~]# kill -9 16949 #逐行讀取passwd文件 [root@localhost ~]# vim read.sh #!/bin/bash cat /etc/passwd | while read line doecho "$line"sleep 1 done :wq [root@localhost ~]# bash read.sh root:x:0:0:root:/root:/bin/bash bin:x:1:1:bin:/bin:/sbin/nologin daemon:x:2:2:daemon:/sbin:/sbin/nologin adm:x:3:4:adm:/var/adm:/sbin/nologin
5. break和continue語句
break 是終止循環。
continue 是跳出當前循環。
[root@localhost ~]# vim test_break.sh #!/bin/bash sum=0 while true doif [ $sum -eq 5 ];thenbreakfilet sum++echo "$sum" done :wq [root@localhost ~]# bash test_break.sh 1 2 3 4 5 [root@localhost ~]# vim test_continue.sh #!/bin/bash sum=0 while true dolet sum++ if [ $sum -eq 5 ];thencontinuefiecho "$sum"sleep 1 done :wq [root@localhost ~]# bash test_continue.sh 1 2 3 4 #跳過了5,僅跳出來此次循環 6 7 8 ^C?
6. case語句(sentos6常用)
case 語句一般用于選擇性來執行對應部分塊命令。
case 模式名??? in
模式 1)
命令
;;
模式 2)
命令
;;
*)
不符合以上模式執行的命令
esac
?
每個模式必須以右括號結束,命令結尾以雙分號結束,最后一個模式不需要添加;;。
[root@localhost ~]# vim test_case.sh#!/bin/bash case $1 in [0-9])echo "數字" ;; [a-z])echo "a-z" ;; [A-Z])a=`tr $1 a-z` #大寫轉化成小寫echo "$a" ;; *)echo "結束" esac :wq [root@localhost ~]# bash test_case.sh 1 數字 [root@localhost ~]# bash test_case.sh a a-z [root@localhost ~]# bash test_case.sh A a-z #內存不足報警#查看內存 [root@localhost ~]# freetotal used free shared buff/cache available Mem: 999936 119616 613732 6856 266588 698092 Swap: 0 0 0 [root@localhost ~]# free -htotal used free shared buff/cache available Mem: 976M 116M 599M 6.7M 260M 681M Swap: 0B 0B 0B [root@localhost ~]# free -h | grep M Mem: 976M 116M 599M 6.7M 260M 681M [root@localhost ~]# free -h | grep M | cut -d'M' -f4599 [root@localhost ~]# free -h | grep M | cut -d'M' -f4 | tr -d ' ' 598 [root@localhost ~]# vim mem_warning.sh #!/bin/bash while true domem=`free -h | grep M | cut -d'M' -f4 | tr -d ' '`if [ $mem -lt 500 ];thenecho '當前內存不足,請及時處理'break #警告一次即可fi done :wq
?
7. 實訓?
1> 寫一個腳本: 實現自動化一鍵部署NFS服務器端和客戶端
#服務端:192.168.16.5;客戶端:192.168.16.6 .5: [root@localhost ~]# vim nfs_auto_client.sh #!/bin/bash mount /dev/cdrom /mnt &>/dev/null yum install rpcbind nfs-utils -y &>/dev/null mkdir /zxj &>/dev/null mount -t nfs 192.168.16.6:/zxj /zxj df -h[root@localhost ~]# vim nfs_auto_server.sh #!/bin/bash #desc: This shell is for auto deploy nfs #date: 2019-05-04 #author: zxj#服務端配置 pack_num=`ls /mnt | wc -l` if [ $pack_num -eq 0 ];thenmount /dev/cdrom /mnt &>/dev/null #檢測是否掛載 fi yum install rpcbind nfs-utils -y &>/dev/null if [ $? -ne 0 ];thenexit fi mkdir /zxj &>/dev/null chown -R nsfnabody: /zxj echo "/zxj 192.168.16.6(rw)" > /etc/exports systemctl restart rpcbind nfs &>/dev/null#客戶端配置 scp ./nfs_auto_client.sh 192.168.16.5:/root ssh 192.168.16.6 bash /root/nfs_auto_client.sh [root@localhost ~]# bash nfs_auto_server.sh
?
2> 第二個腳本:實現批量化檢測當前教室主機在線狀況,在線主機保存至一個文件中?
3> 第三個腳本:實現批量化創建100個用戶,并創建8位隨機密碼,且可登陸
#!/bin/bash for i in {1..100} douseradd user$ipasswd=`echo $RANDOM | md5sum | cut -c 1-8`echo $passwd | passwd --stdin user$iecho -e "賬戶:user$ \n密碼:$passwd" done?
4> 第四個腳本:找出系統中含有某個關鍵詞的文件,并輸出到終端,關鍵詞用戶輸入指定
[root@localhost ~]# vim find_key.sh #!/bin/bash read -p "Please input your keyword:" key for file in `find / -type f`` doif grep "$key" $file &>/dev/null;thenecho "$file"fi done :wq [root@localhost ~]# bash find_key.sh Please input your keyword:anaconda /boot/grub2/device.map ……?
5> 第五個腳本:批量判斷當前目錄下所有文件類型?
[root@localhost ~]# vim type.sh #!/bin/bash for file in `ls /root` dotype=`ls -ld $file | cut -c 1`if [ "$type" == "-" ];thenecho "$type------->$file=====普通文件"elif [ "$type" == "d" ];thenecho "$type------->$file=====目錄文件" elif [ "$type" == "l" ];thenecho "$type------->$file=====鏈接文件"elseecho "$type------->$file=====未知文件"fi done :wq [root@localhost ~]# bash type.sh -------->anaconda-ks.cfg=====普通文件 -------->find_key.sh=====普通文件 -------->type.sh=====普通文件?
6> 找到以.sh結尾的文件,計算文件大小總和,以KB為單位?
?
#方法一: 用cut分割 [root@localhost ~]# vim sum_sh.sh #!/bin/bash sum=0 for file in `find / -name "*.sh"` dosize=`ls -l $file | cut -d " " -f 5`let sum+=$size done echo "$(($sum/1024))KB" [root@localhost ~]# bash sum_sh.sh 623KB# 方法二:用awk分割 [root@localhost ~]# vim sum_sh1.sh #!/bin/bash sum=0 for file in `find / -name "*.sh"` dosize=`ls -l $file | awk -F " +" '{printf $5}'`let sum+=$size done echo "$(($sum/1024))KB" :wq [root@localhost ~]# bash sum_sh1.sh 623KB轉載于:https://www.cnblogs.com/ajunyu/p/10887003.html
總結
- 上一篇: leetcode 925. 长按键入
- 下一篇: 找到数组中和为给定值的两个数