[Shell]條件判斷與流程控制:if, case, for, while, until
【條件判斷】
1. 按文件類型進行判斷
-b 文件 判斷該文件是否存在,並且為塊設備文件(是塊設備文件為真)
-c 文件 判斷該文件是否存在,並且為字符設備文件(是字符設備文件為真)
-d 文件 判斷該文件是否存在,並且為目錄文件(是目錄為真)
-e 文件 判斷該文件是否存在(存在為真)
-f 文件 判斷該文件是否存在,並且為普通文件(是普通文件為真)
-L 文件 判斷該文件是否存在,並且為符號鏈接文件(是符號鏈接文件為真)
-p 文件 判斷該文件是否存在,並且為管道文件(是管道文件為真)
-s 文件 判斷該文件是否存在,並且為非空(非空為真)
-S 文件 判斷該文件是否存在,並且為套接字文件(是套接字文件為真)
兩種判斷格式:
① test -e /root/install.log
② [ -e /root/install.log ]
[ -f /root/install.log ] && echo ‘yes‘ || echo ‘no‘
2. 按照文件權限進行判斷(不區分所有者, 所屬組)
-r 文件 判斷該文件是否存在,並且擁有讀權限(有讀權限為真)
-w 文件 判斷該文件是否存在,並且擁有寫權限(有寫權限為真)
-x 文件 判斷該文件是否存在,並且擁有執行權限(有執行權限為真)
-u 文件 判斷該文件是否存在,並且擁有SUID權限(有SUID權限為真)
-g 文件 判斷該文件是否存在,並且擁有SGID權限(有SGID權限為真)
-k 文件 判斷該文件是否存在,並且擁有SBit權限(有SBit權限為真)
3. 兩個文件之間進行比較
文件1 -nt 文件2 判斷文件1的修改時間是否比文件2的新(如果新則為真)
文件1 -ot 文件2 判斷文件1的修改 時間是否比文件2的舊
文件1 -ef 文件2 判斷文件1是否和文件2的Inode號一致,可以理解為兩個文件是否為同一個文件。這個判斷用於判斷硬鏈接是很好的方法。
4. 兩個整數之間比較
整數1 -eq 整數2 判斷整數1是否和整數2相等(相等為真)
整數1 -ne 整數2 判斷整數1是否和整數2不相等(不相等為真)
整數1 -gt 整數2 判斷整數1是否大於整數2(大於為真)
整數1 -lt 整數2 判斷整數1是否大於整數2(小於為真)
整數1 -ge 整數2 判斷整數1是否大於等於整數2(大於等於為真)
整數1 -le 整數2 判斷整數1是否小於等於整數2(小於等於為真)
[ 1 eq 2 ] && echo ‘yes‘ || echo ‘no‘
5. 字符串的判斷
-z 字符串 判斷字符串是否為空(為空返回真)
-n 字符串 判斷字符串是否為非空(非空返回真)
字符串1 == 字符串2 判斷字符串1和字符串2是否相等(相等返回真)
字符串1 != 字符串2 判斷字符串1是否和字符串2不相等(不相等返回真)
name=chen
[ -z "$name" ] && echo ‘yes‘ || echo ‘no‘
6. 多重條件判斷
判斷1 -a 判斷2 邏輯與,判斷1和判斷2都成立,最終的結果才為真
判斷1 -o 判斷2 邏輯或,判斷1和判斷2有一個成立,最終的結果就為真
! 判斷 邏輯非,使原始的判斷式取反
a=24
[ -n "$a" -a "$a" -gt 23 ] && echo ‘yes‘ || echo ‘no‘
【流程控制 - if 語句】
1. 單分支if條件語句
if [ 條件判斷式 ]; then 程序 fi
if test -z "$ac_version"; then? 程序 fi
或者
if [ 條件判斷式 ] then 程序 fi
註意:
① if開頭,fi結尾
② [ 條件判斷式 ]就是使用test命令判斷,所以中括號和條件判斷式之間必須有空格
③ then後面跟符合條件之後執行的程序,可以放在[]之後,用" ; "分割,也可以換行寫入,就不需要" ; "了。
#!/bin/bash # 統計根分區使用率 rate=$(df -h | grep "/dev/sda3" | awk ‘{print $5}‘ | cut -d "%" -f1) # 把根分區使用率作為變量值賦予變量rate if [ $rate -ge 80 ]; then echo "Warning! /dev/sda3 is full !" fi
2. 雙分支if條件語句
if [ 條件判斷式 ] then 條件成立時,執行的程序 else 條件不成立時,執行的另一個程序 fi
#!/bin/bash # 備份mysql數據庫 ntpdate asia.pool.ntp.org &> /dev/null # 同步系統時間(需聯網) date=$(date +%y%m%d) # 把當前系統時間按照"年月日"格式賦予變量date size=$(du -sh /var/lib/mysql) # 統計mysql數據庫的大小,並把大小賦予size變量 if [ -d /tmp/dbbak ] then echo "Date: $date!" > /tmp/dbbak/dbinfo.txt
echo "Data size: $size" >> /tmp/dbbak/dbinfo.txt
cd /tmp/dbbak
tar -zcf mysql-lib-$date.tar.gz /var/lib/mysql dbinfo.txt
&> /dev/null # 把所有輸出丟棄
rm -rf /tmp/dbbak/dbinfo.txt # 卸磨殺驢 else mkdir /tmp/dbbak ... fi
#!/bin/bash # 判斷Apache是否啟動 ( 先安裝nmap:rpm -ivh http://nmap.org/dist/nmap-4.68-1.i386.rpm ) port=$(nmap -sT 192.168.1.156 | grep tcp | grep http | awk ‘{print $2}‘) # 使用nmap命令掃描服務器,並截取apache服務的狀態,賦予變量port
if [ "$port" == "open" ] then echo "$(date) httpd is ok!" >> /tmp/httpd-acc.log # 如果狀態正常,追加到日誌中 else /etc/rc.d/init.d/httpd start &> /dev/null # 把所有輸出丟棄 echo "$(date) httpd reboot!" >> /tmp/httpd-err.log # 重啟記錄追加到錯誤日誌 fi
3. 多分支if條件語句
if [ 條件判斷式1 ] then 當條件判斷式1成立時,執行程序1 elif [ 條件判斷式2 ] then 當條件判斷式2成立時,執行程序2 ...更多判斷... else 當所有條件都不成立時,最後執行此程序 fi
#!/bin/bash # 判斷用戶輸入的是什麽文件 read -p "Please input a filename:" file # 接收鍵盤的輸入,並賦予變量file if [ -z "$file" ] then echo "Error, please input a filename" exit 1 elif [ ! -e "$file" ] # 判斷file的值是否存在 then echo "Your input is not a file!" exit 2 elif [ -f "$file" ] # 判斷file的值是否為普通文件 then echo "$file is a regular fie!" elif [ -d "$file" ] then echo "$file is a directory!" else echo "$file is an other file!" fi
【流程控制 - case 語句】
多分支case條件語句:case語句只能判斷一種條件關系,而if語句可以判斷多種條件關系。
case $變量名 in "值1") 如果變量的值等於值1,則執行程序1 ;; "值2")
如果變量的值等於值2,則執行程序2 ;; *) 如果變量的值都不是以上的值,則執行此程序 ;; esac
#!/bin/bash # 判斷用戶輸入
read -p "Please choose yes/no" -t 30 cho case $cho in "yes") echo "You choose yes" ;; "no") echo "You choose no" ;; *) echo "You choose none" ;; esac
【流程控制 - for 循環】
語法1:
for 變量 in 值1 值2 值3... ; do 程序 done
語法2:
for (( 初始值; 循環控制條件; 變量變化 )) do 程序 done
#!/bin/bash # 打印時間
for time in morning noon afternoon evening ; do echo "This time is $time" done for i in 1 2 3 4 ; do echo $i done
#!/bin/bash # 批量解壓縮腳本 cd /lnmp ls *.tar.gz > ls.log for i in $(cat ls.log) ; do tar -zxf $i &> /dev/null done rm -rf /lnmp/ls.log
#!/bin/bash # 求和 s=0 for (( i=1; i<=100; i++ )) ; do s=$(( $s + $i )) done
echo "The sum of 1+2+3+...+100 is : $s"
#!/bin/bash # 批量添加指定數量的用戶 read -p "Please input user name:" -t 30 name read -p "Please input the number of users:" -t 30 num read -p "Please input the password of users:" -t 30 pass # -a用於連續多個條件判斷 if [ ! -z "$name" -a ! -z "$num" -a ! -z "$pass" ] then y=$(echo $num | sed ‘s/^[0-9]*$//g‘) # 任意數字替換為空 if [ -z "$y" ] # 如果y的值是空,則num是數字 then for (( i=0; i<=$num; i++ )) do /usr/sbin/useradd $name$i &> /dev/null echo $pass | /usr/bin/passwd --stdin "$name$i" &> /dev/null done fi fi
【流程控制 - while 和 until 循環】
while循環是條件循環,只要條件判斷式成立,循環就會一直繼續,直到條件判斷式不成立,循環才會停止。
while [ 條件判斷式 ] do 程序 done
#!/bin/bash # 示例用法 while [ $# -gt 0 ]; do case "$#" in 3) echo "第一個參數是$1, 參數個數是$#" ;; 4) echo "第一個參數是$1, 參數個數是$#" ;; *) echo ‘What happened‘ ;; esac # 與case對應構成case語句,形如if和fi case "$#" in abc) ... ;; esac shift # 用shift命令把位置參數左移 done
運行如:./example.sh 3 4 5
until循環:和while循環相反,until循環時只要條件判斷式不成立則進行循環,並執行循環程序。一旦循環條件成立,則終止循環。
#!/bin/bash i=1 s=0 until [ "$i" -gt 100 ] # 循環直到變量i的值大於100就停止循環 do s=$(( $i + $s)) i=$(( $i + 1 )) done
echo "The sum is : $i"
【總結】
Shell適用:幫助管理員減少重復操作或進行運維操作,不適合進行復雜的運算的場合。
如何建立編程思想:學習,練習,知道讓程序幫你幹什麽。
[Shell]條件判斷與流程控制:if, case, for, while, until