目錄
前言:
一、條件測試
1、檔案測試
2、整數值比較
3、字元串比較
4、邏輯測試
二、if語句
1、單分支結構
2、雙分支結構
3、多分支結構
三、case分支語句
總結:
前言:
學習條件語句能夠讓我們處理更加複雜多變得系統任務,這裡将學習if和case程式控制語句。
一、條件測試
Shell環境根據指令執行後的傳回狀态值(0?)來判斷是否執行成功,當傳回值為0時表示成功,
否則(非0值)表示失敗或異常。使用專門的測試工具-test指令可以對特定條件進行測試,并根據返
回值來判斷條件是否成立(傳回值為0表示條件成立)。
文法格式:test 條件表達式
或:[條件表達式] (注意中括号和表達式中間需要隔一個空格。)
兩種方式的作用完全相同,後一種較為常用,也更貼近程式設計習慣。根據需要測試的條件類别不
同,條件表達式也不同。比較常用的條件操作包括檔案測試、整數值比較、字元串比較、以及針對
多個條件的邏輯測試。
1、檔案測試
檔案測試指的是根據給定的路徑名稱,判斷對應的是檔案還是目錄,或者判斷檔案是否可讀、
可寫、可執行等。檔案測試的常見操作選項如下,使用時将測試對象放在操作選項之後即可。
test檔案測試選項含義: | |
-d | 測試是否為目錄(Directory)。 |
-e | 測試目錄或檔案是否存在(Exist)。 |
-f | 測試是否為檔案(File)。 |
-r | 測試目前使用者是否有權限讀取(Read)。 |
-w | 測試目前使用者是否有權限寫入(Write)。 |
-x | 測試是否設定有可執行(Excute)權限。 |
-b | 測試是否為裝置檔案。 |
-c | 測試是否為字元裝置檔案。 |
-s | 測試存在且檔案大小為空。 |
-L | 測試是否為連結檔案(軟連結) |
-nt | 判斷檔案A是否比檔案B新 |
-ot | 判斷檔案A是否比檔案B舊 |
-ef | 判斷兩個檔案是否為同一個檔案,判斷兩檔案是否指向同一個inode |
執行條件測試操作後,通過預定義變量$?可以獲得測試指令的傳回狀态值,進而判斷該條件
是否成立。
[[email protected] mytext]# [ ! -e /home/kangl ] && mkdir /home/kangl
[[email protected] mytext]# ls /home/
kangl kl
[[email protected] mytext]# echo $?
0
[[email protected] mytext]# [ ! -e /home/kangl ] && mkdir /home/kangl
[[email protected] mytext]# echo $?
1
[[email protected] mytext]# test a -ot b && echo 1 || echo 0
2、整數值比較
整數值比較指的是根據給定的兩個整數值,判斷第一個數與第二個數的關系,如是否大于、等
于、小于第二個數。整數值比較的常用操作選項如下,使用時将操作選項放在要比較的兩個整數之
間。
常用測試操作符: | |
-eq | 第一個數等于(Equal)第二個數。 |
-ne | 第一個數不等于(Not Equal)第二個數。 |
-gt | 第一個數大于(Greater Than)第二個數。 |
-lt | 第一個數小于(Lesser Than)第二個數。 |
-le | 第一個數小于或等于(Lesser or Equal)第二個數。 |
-ge | 第一個數大于或等于(Greateror Equal)第二個數 |
應用如下:
[[email protected] mytext]# who
root pts/0 2021-09-03 21:50 (192.168.90.10)
[[email protected] mytext]# who | wc -l
1
[[email protected] mytext]# [ $(who|wc -l) -le 5 ] && echo "使用者太少……"
使用者太少……
[[email protected] mytext]# [ $(who|wc -l) -ge 1 ] && echo "使用者太duo……"
使用者太duo……
[[email protected] mytext]# neicun=$(free -m | grep "Mem:" | awk '{print $4}')#檢視記憶體占用
[[email protected] mytext]# [ ! $neicun -le 800 ] && echo "伺服器記憶體大" #這裡!為取反
伺服器記憶體大
[[email protected] mytext]#
3、字元串比較
字元串比較通常用來檢查使用者輸入、系統環境等是否滿足條件,在提供互動式操作的Shell腳
本中,也可用來判斷使用者輸入的位置參數是否符合要求。
字元串比較的常用操作選項: | |
選項 | 含義 |
=: | 第一個字元串與第二個字元串相同。 |
!= | 第一個字元串與第二個字元串不相同,其中"!"符号表示取反。 |
-z | 檢查字元串是否為空(zero),對于未定義或賦予空值的變量将視為空串。 |
-n | 檢查字元串有 |
測試指令條件格式: [字元串1 = 字元串2]
[字元串1 != 字元串2]
或: [ -z 字元串]

執行指令注意中英文差別。
應用如下:
[[email protected] mytext]# echo $LANG
zh_CN.UTF-8
[[email protected] mytext]# [ $LANG != "en.US" ] && echo "not en.US"
not en.US
[[email protected] mytext]# echo $? #判斷變量是否為空字元
0
[[email protected] mytext]# read -p "yes/no :" ACK
yes/no :^C
[[email protected] mytext]# [ -z $ACK ]
[[email protected] mytext]# echo $?
0
[[email protected] mytext]# read -p "yes/no :" ACK
yes/no :no
[[email protected] mytext]# [ -n $ACK ]
[[email protected] mytext]# echo $?
4、邏輯測試
邏輯測試指的是判斷兩個或多個條件之間的依賴關系。當系統任務取決于多個不同的條件時,
根據這些條件是否同時成立或者隻要有其中一個成立等情況,需要有一個測試的過程。
常用的邏輯測試操作如下,使用時放在不同的測試語句或指令之間。
邏輯測試操作選項: | |
選項 | 含義 |
&& | 邏輯與,表示"而且",隻有目前後兩個條件都成立時,整個測試指令的傳回值才為0(結果成立)。使用test指令測試時,"&&"可改為"-a”。 |
|| | 邏輯或,表示“或者”,隻要前後兩個條件中有一個成立,整個測試指令的傳回值即為0(結果成立)。使用test指令測試時,"||"可改為”-o”。 |
! | 邏輯否,表示"不",隻有當指定的條件不成立時,整個測試指令的傳回值才為0(結果成立)。 |
邏輯測試條件表達式格式: [表達式1] 操作符 [表達式2]
或:指令1 操作符 指令2
應用如下:
[[email protected] mytext]# [ -d /mytext/ ] && [ -r /mytext/ ] && echo "兩個表達式都滿足"
兩個表達式都滿足
[[email protected] mytext]# [ -d /mytext/ ] && [ -f /mytext/ ] && echo "兩個表達式都滿足"
[[email protected] mytext]# [ -d /mytext/ ] && [ ! -f /mytext/ ] && echo "兩個表達式都滿足"
兩個表達式都滿足
[[email protected] mytext]# [ -d /home/cc.txt/ ] || [ -d /mytext/1.txt ] && echo "滿足其中之一"
[[email protected] mytext]# [ -d /home/ ] || [ -d /mytext/1.txt ] && echo "滿足其中之一"
滿足其中之一
[[email protected] mytext]# uname -r #檢視核心
3.10.0-693.el7.x86_64
[[email protected] mytext]# Mnum=$(uname -r | awk -F. '{print $1}')
[[email protected] mytext]# Snum=$(uname -r | awk -F. '{print $2}')
[[email protected] mytext]# [ $Mnum -ge 3 ] && [ $Snum -gt 6 ] && echo "true"
true
補充:
中括号[ ]、中雙括号[[ ]]與它中間的符合關系:
[[email protected] mytext]# a=2
[[email protected] mytext]# b=4
[[email protected] mytext]# [[ $a -ge 1 && $b -ge 3 ]]
[[email protected] mytext]# echo $?
0
[[email protected] mytext]# [ $a -ge 1 -a $b -ge 3 ]
[[email protected] mytext]# echo $?
0
二、if語句
在shell腳本應用中,if語句時最為常用的一種流程控制方式,用來根據特定的條件測試結果,
分别執行不同的操作(如果……那麼……)。if語句的選擇結果可分為三種基本類型,适用于不同
的應用場合。
1、單分支結構
if語句的“分支”指的是不同測試結果所對應的執行語句(一條或多條)。對于單分支的選擇結
構,隻有在“條件成立”時才會執行相應的代碼,否則不執行任何操作。
單分支if語句的執行流程:首先判斷條件測試作的結果,如果傳回值為0,表示條件成立,則
執行then後面的指令序列,一直到遇見結束判斷為止,繼續執行其他腳本代碼;如果傳回值不為
0,則忽略then後面的指令序列,直接跳至行以後執行其他腳本代碼,結構如圖所示。
應用如下:
#!/bin/bash
……
if ls /opt > /dev/null
then
echo "它正确"
fi
……
2、雙分支結構
雙分支選擇結構,要求針對“條件成立”、“條件不成立”兩種情況分别執行不同的操作。
雙分支if語句的執行流程:首先判斷條件測操作的結果,如果條件成立,則執行then後面的命
令序列1,忽略clse及後面指令序列2,直到遇見fi結束判斷;如果條件不成立,則忽略then及後面
的指令序1,直接跳至else後面的指令序列2并執行,直到遇見f結束判斷,結構如圖所示。
應用如下:
#!/bin/bash
……
IP=192.168.90.30
ping -c 3 -i 0.2 -W 3 $IP &>/dev/null
if [ $? -eq 0 ];then echo "$IP 已連接配接";else echo "$IP 未連接配接";fi
……
3、多分支結構
多分支就是if語句根據測試結果,然後跟else一起嵌套使用,進行多次判斷。
多分支if語句的執行流程:首先判斷條件測試操作1的結果,如果條件1成立,則執行指令序列
1,然後跳至結束判斷;果條件1不成立,則繼續判斷條件測試操作2的結果,如果條件2成立,則
執行命序列2,然後跳至結束判斷……如果所有的條件都不滿足,則執行else後面的指令列n,直到
遇見fi結束判斷。結構如圖示。
應用如下:
#! /bin/bash
#if語句多分支結構
read -p "請輸入你的分數(0~100):" num
if [ $num -ge 85 -a $num -le 100 ];then echo "優秀"
elif [ $num -ge 60 -a $num -lt 85 ];then echo "良好"
elif [ $num -lt 60 ];then echo "不合格"
elif [ $num -gt 100 ];then echo "請輸入正确的分數"
fi
……
三、case分支語句
case語句主要适用于以下情況:某個變量在多種取值,需要對其中的每一種取值分别執行不同
的指令序列。這種情況與多分支的if語句非常相似,隻不過if語句需要判斷多個不同的條件,而case
語句隻是判一個變量的不同取值。
關鍵字case後面跟的是“變量值”,即“$變量名”,這點需要與for循環語句的結構加以差別。整
個分支構包括在case…esac之間,中間的模式1、模式2、…、*對應為變量的不同取值(程式期
望的取值),其中*作為通配符,可比對任意值。
case語句的執行流程:首先使用“變量值”與模式1進行比較,若取值相同則執行模式1後的命
令序列,直到遇見雙分号“;;”後轉至esac,表示結束分支;若與模式1不相比對,則繼續與模式2
進行比較,若取值相同則執行模式2後的指令序列,直到遇見雙分号“;;”後跳轉至esac,表示結
束分……以此類推,若找不到任何比對的值,則執行預設模式“*)”後的指令序列,直到遇esac後
結束分支。如圖示:
注意:
● case行尾必須為單詞“in”,每一模式必須以右括号“)”結束。
● 雙分号“;;”表示指令序列的結束。
● 模式字元串中,可以用方括号表示一個連續的範圍,如“[0-9]”;還可以用豎杠符号“|”表
示或,如“A|B”。
● 最後的“*)”表示預設模式,其中的*相當于通配符。
應用如下:
#!/bin/bash
case $1 in
start)
/usr/bin/systemctl $1 httpd
/usr/bin/ps qux | grep httpd
echo "httpd start"
;;
stop)
/usr/bin/systemctl $1 httpd
/usr/bin/ps qux | grep httpd
echo "httpd stop"
;;
restart)
echo "httpd stop...... "
/usr/bin/ps qux | grep httpd
/usr/bin/systemctl $1 httpd
echo "httpd restart......"
/usr/bin/ps qux | grep httpd
;;
status)
/usr/bin/systemctl $1 httpd
;;
*)
echo "plases input restart/start/status/stop"
……
總結:
注意if和case程式控制語句的差別,靈活運用能夠輕松完成複雜的工作。