03_SHELL程式設計之條件判斷和流程控制
文章目錄
本節課程目標
- 熟悉條件判斷語句,如判斷整數、判斷字串等
- 熟悉流程控制語句基本語法,如if…else…
一、條件判斷語法結構
思考:何為真(true)?何為假(false)?
##1. 條件判斷語法格式
- 格式1: test 條件表示式
- 格式2: [ 條件表示式 ]
- 格式3: [[ 條件表示式 ]] 支援正則
- 注意:使用**[ ]** 或者 [[ ]],這種條件判斷不支援 , > ,< ,== ,等表示式 ,只支援-eq ,-lq -lt等等進行判斷
特別說明:
1)[ 親親,我兩邊都有空格,不空打死你呦 ] ?
2)[[ 親親,我兩邊都有空格,不空打死你呦 ]]?
- 更多判斷,
man test
去檢視,很多的引數都用來進行條件判斷
2. 條件判斷相關引數
問:你要判斷什麼?
答:我要判斷檔案型別,判斷檔案新舊,判斷字串是否相等,判斷許可權等等…
㈠ 判斷檔案型別
判斷引數 | 含義 |
---|---|
-e | 判斷檔案是否存在(任何型別檔案) |
-f | 判斷檔案是否存在並且是一個普通檔案 |
-d | 判斷檔案是否存在並且是一個目錄 |
-L | 判斷檔案是否存在並且是一個軟連線檔案 |
-b | 判斷檔案是否存在並且是一個塊裝置檔案 |
-S | 判斷檔案是否存在並且是一個套接字檔案 |
-c | 判斷檔案是否存在並且是一個字元裝置檔案 |
-p | 判斷檔案是否存在並且是一個命名管道檔案 |
-s | 判斷檔案是否存在並且是一個非空檔案(有內容) |
舉例說明:
test -e file 只要檔案存在條件為真
[ -d /shell01/dir1 ] 判斷目錄是否存在,存在條件為真
[ ! -d /shell01/dir1 ] 判斷目錄是否存在,不存在條件為真
[[ -f /shell01/1.sh ]] 判斷檔案是否存在,並且是一個普通的檔案
㈡ 判斷檔案許可權
判斷引數 | 含義 |
---|---|
-r | 當前使用者對其是否可讀 |
-w | 當前使用者對其是否可寫 |
-x | 當前使用者對其是否可執行 |
-u | 是否有suid,高階許可權冒險位 |
-g | 是否sgid,高階許可權強制位 |
-k | 是否有t位,高階許可權粘滯位 |
㈢ 判斷檔案新舊
說明:這裡的新舊指的是檔案的修改時間。
判斷引數 | 含義 |
---|---|
file1 -nt file2 | 比較file1是否比file2新 |
file1 -ot file2 | 比較file1是否比file2舊 |
file1 -ef file2 | 比較是否為同一個檔案,或者用於判斷硬連線,是否指向同一個inode |
㈣ 判斷整數
判斷引數 | 含義 |
---|---|
-eq | 相等 |
-ne | 不等 |
-gt | 大於 |
-lt | 小於 |
-ge | 大於等於 |
-le | 小於等於 |
㈤ 判斷字串
判斷引數 | 含義 |
---|---|
-z | 判斷是否為空字串,字串長度為0則成立 |
-n | 判斷是否為非空字串,字串長度不為0則成立 |
string1 = string2 | 判斷字串是否相等 |
string1 != string2 | 判斷字串是否相不等 |
㈥ 多重條件判斷
判斷符號 | 含義 | 舉例 |
---|---|---|
-a 或 && | 邏輯與 | [ 1 -eq 1 -a 1 -ne 0 ] [ 1 -eq 1 ] && [ 1 -ne 0 ] |
-o 或 || | 邏輯或 | [ 1 -eq 1 -o 1 -ne 1 ] |
特別說明:
&& 前面的表示式為真,才會執行後面的程式碼
|| 前面的表示式為假,才會執行後面的程式碼
; 只用於分割命令或表示式
① 舉例說明
- 數值比較
[root@server ~]# [ $(id -u) -eq 0 ] && echo "the user is admin"
[root@server ~]$ [ $(id -u) -ne 0 ] && echo "the user is not admin"
[root@server ~]$ [ $(id -u) -eq 0 ] && echo "the user is admin" || echo "the user is not admin"
[root@server ~]# uid=`id -u`
[root@server ~]# test $uid -eq 0 && echo this is admin
this is admin
[root@server ~]# [ $(id -u) -ne 0 ] || echo this is admin
this is admin
[root@server ~]# [ $(id -u) -eq 0 ] && echo this is admin || echo this is not admin
this is admin
[root@server ~]# su - stu1
[stu1@server ~]$ [ $(id -u) -eq 0 ] && echo this is admin || echo this is not admin
this is not admin
- 類C風格的數值比較
注意:在(( ))中,=表示賦值;==表示判斷
[root@server ~]# ((1==2));echo $?
[root@server ~]# ((1<2));echo $?
[root@server ~]# ((2>=1));echo $?
[root@server ~]# ((2!=1));echo $?
[root@server ~]# ((`id -u`==0));echo $?
[root@server ~]# ((a=123));echo $a
[root@server ~]# unset a
[root@server ~]# ((a==123));echo $?
- 字串比較
注意:雙引號引起來,看作一個整體;= 和 == 在 [ 字串 ] 比較中都表示判斷
[root@server ~]# a='hello world';b=world
[root@server ~]# [ $a = $b ];echo $?
[root@server ~]# [ "$a" = "$b" ];echo $?
[root@server ~]# [ "$a" != "$b" ];echo $?
[root@server ~]# [ "$a" !== "$b" ];echo $? 錯誤
[root@server ~]# [ "$a" == "$b" ];echo $?
[root@server ~]# test "$a" != "$b";echo $?
test 表示式
[ 表示式 ]
[[ 表示式 ]]
思考:[ ] 和 [[ ]] 有什麼區別?
[root@server ~]# a=
[root@server ~]# test -z $a;echo $?
[root@server ~]# a=hello
[root@server ~]# test -z $a;echo $?
[root@server ~]# test -n $a;echo $?
[root@server ~]# test -n "$a";echo $?
# [ '' = $a ];echo $?
-bash: [: : unary operator expected
2
# [[ '' = $a ]];echo $?
0
[root@server ~]# [ 1 -eq 0 -a 1 -ne 0 ];echo $?
[root@server ~]# [ 1 -eq 0 && 1 -ne 0 ];echo $?
[root@server ~]# [[ 1 -eq 0 && 1 -ne 0 ]];echo $?
② 邏輯運算子總結
- 符號;和&&和||都可以用來分割命令或者表示式
- 分號(;)完全不考慮前面的語句是否正確執行,都會執行;號後面的內容
&&
符號,需要考慮&&前面的語句的正確性,前面語句正確執行才會執行&&後的內容;反之亦然||
符號,需要考慮||前面的語句的非正確性,前面語句執行錯誤才會執行||後內容;反之亦然- 如果&&和||一起出現,從左往右依次看,按照以上原則
二、流程控制語句
關鍵詞:選擇(人生漫漫長路,我該何去何從?)
1. 基本語法結構
㈠ if結構
箴言1:只要正確,就要一直向前衝✌️
F:表示false,為假
T:表示true,為真
if [ condition ];then
command
command
fi
if test 條件;then
命令
fi
if [[ 條件 ]];then
命令
fi
[ 條件 ] && command
㈡ if…else結構
箴言2:分叉路口,二選一
if [ condition ];then
command1
else
command2
fi
[ 條件 ] && command1 || command2
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-px0yLNy9-1606830223613)(/流程判斷2.png)]
小試牛刀:
讓使用者自己輸入字串,如果使用者輸入的是hello,請列印world,否則列印“請輸入hello”
read定義變數
- if…else…
#!/bin/env bash
read -p '請輸入一個字串:' str
if [ "$str" = 'hello' ];then
echo 'world'
else
echo '請輸入hello!'
fi
1 #!/bin/env bash
2
3 read -p "請輸入一個字串:" str
4 if [ "$str" = "hello" ]
5 then
6 echo world
7 else
8 echo "請輸入hello!"
9 fi
echo "該指令碼需要傳遞引數"
1 if [ $1 = hello ];then
2 echo "hello"
3 else
4 echo "請輸入hello"
5 fi
#!/bin/env bash
A=hello
B=world
C=hello
if [ "$1" = "$A" ];then
echo "$B"
else
echo "$C"
fi
read -p '請輸入一個字串:' str;
[ "$str" = 'hello' ] && echo 'world' || echo '請輸入hello!'
㈢ if…elif…else結構
箴言3:選擇很多,能走的只有一條
if [ condition1 ];then
command1 結束
elif [ condition2 ];then
command2 結束
else
command3
fi
註釋:
如果條件1滿足,執行命令1後結束;如果條件1不滿足,再看條件2,如果條件2滿足執行命令2後結束;如果條件1和條件2都不滿足執行命令3結束.
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-UPRc6qhR-1606830223615)(/流程判斷3.png)]
㈣ 層層巢狀結構
箴言4:多次判斷,帶你走出人生迷霧。
if [ condition1 ];then
command1
if [ condition2 ];then
command2
fi
else
if [ condition3 ];then
command3
elif [ condition4 ];then
command4
else
command5
fi
fi
註釋:
如果條件1滿足,執行命令1;如果條件2也滿足執行命令2,如果不滿足就只執行命令1結束;
如果條件1不滿足,不看條件2;直接看條件3,如果條件3滿足執行命令3;如果不滿足則看條件4,如果條件4滿足執行命令4;否則執行命令5
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-GIJKFjP5-1606830223618)(/流程判斷4.png)]
2. 應用案例
㈠ 判斷兩臺主機是否ping通
**需求:**判斷當前主機是否和遠端主機是否ping通
① 思路
- 使用哪個命令實現
ping -c次數
- 根據命令的執行結果狀態來判斷是否通
$?
- 根據邏輯和語法結構來編寫指令碼(條件判斷或者流程控制)
② 落地實現
#!/bin/env bash
# 該指令碼用於判斷當前主機是否和遠端指定主機互通
# 互動式定義變數,讓使用者自己決定ping哪個主機
read -p "請輸入你要ping的主機的IP:" ip
# 使用ping程式判斷主機是否互通
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "當前主機和遠端主機$ip是互通的"
else
echo "當前主機和遠端主機$ip不通的"
fi
邏輯運算子
test $? -eq 0 && echo "當前主機和遠端主機$ip是互通的" || echo "當前主機和遠端主機$ip不通的"
㈡ 判斷一個程式是否存在
**需求:**判斷web伺服器中httpd程式是否存在
① 思路
- 檢視程式的相關命令 ps top pgrep
- 根據命令的返回狀態值來判斷程式是否存在
- 根據邏輯用指令碼語言實現
② 落地實現
#!/bin/env bash
# 判斷一個程式(httpd)的程式是否存在
pgrep httpd &>/dev/null
if [ $? -ne 0 ];then
echo "當前httpd程式不存在"
else
echo "當前httpd程式存在"
fi
或者
test $? -eq 0 && echo "當前httpd程式存在" || echo "當前httpd程式不存在"
③ 補充命令
pgrep命令:以名稱為依據從執行程式佇列中查詢程式,並顯示查詢到的程式id
選項
-o:僅顯示找到的最小(起始)程式號;
-n:僅顯示找到的最大(結束)程式號;
-l:顯示程式名稱;
-P:指定父程式號;pgrep -p 4764 檢視父程式下的子程式id
-g:指定程式組;
-t:指定開啟程式的終端;
-u:指定程式的有效使用者ID。
㈢ 判斷一個服務是否正常
**需求:**判斷入口網站是否能夠正常訪問
① 思路
- 可以判斷程式是否存在,用/etc/init.d/httpd status判斷狀態等方法
- 最好的方法是直接去訪問一下,通過訪問成功和失敗的返回值來判斷
- Linux環境,wget curl elinks -dump
② 落地實現
#!/bin/env bash
# 判斷入口網站是否能夠正常提供服務
#定義變數
web_server=www.itcast.cn
#訪問網站
wget -P /shell/ $web_server &>/dev/null
[ $? -eq 0 ] && echo "當前網站服務是ok" && rm -f /shell/index.* || echo "當前網站服務不ok,請立刻處理"
##3. 課堂練習
㈠ 判斷使用者是否存在
**需求1:**輸入一個使用者,用指令碼判斷該使用者是否存在
#!/bin/env bash
2 read -p "請輸入一個使用者名稱:" user_name
3 id $user_name &>/dev/null
4 if [ $? -eq 0 ];then
6 echo "該使用者存在!"
7 else
8 echo "使用者不存在!"
9 fi
#!/bin/bash
# 判斷 使用者(id) 是否存在
read -p "輸入壹個使用者:" id
id $id &> /dev/null
if [ $? -eq 0 ];then
echo "該使用者存在"
else
echo "該使用者不存在"
fi
#!/bin/env bash
read -p "請輸入你要查詢的使用者名稱:" username
grep -w $username /etc/passwd &>/dev/null
if [ $? -eq 0 ]
then
echo "該使用者已存在"
else
echo "該使用者不存在"
fi
#!/bin/bash
read -p "請輸入你要檢查的使用者名稱:" name
id $name &>/dev/null
if [ $? -eq 0 ]
then
echo 使用者"$name"已經存在
else
echo 使用者"$name"不存在
fi
#!/bin/env bash
#判斷使用者是否存在
read -p "請寫出使用者名稱" id
id $id
if [ $? -eq 0 ];then
echo "使用者存在"
else
echo "使用者不存在"
fi
#!/bin/env bash
read -p '請輸入使用者名稱:' username
id $username &>/dev/null
[ $? -eq 0 ] && echo '使用者存在' || echo '不存在'
㈡ 判斷軟體包是否安裝
**需求2:**用指令碼判斷一個軟體包是否安裝,如果沒安裝則安裝它(假設本地yum已配合)
㈢ 判斷當前主機的核心版本
**需求3:**判斷當前核心主版本是否為2,且次版本是否大於等於6;如果都滿足則輸出當前核心版本
思路:
1. 先檢視核心的版本號 uname -r
2. 先將核心的版本號儲存到一個變數裡,然後再根據需求擷取出該變數的一部分:主版本和次版本
3. 根據需求進步判斷
#!/bin/bash
kernel=`uname -r`
var1=`echo $kernel|cut -d. -f1`
var2=`echo $kernel|cut -d. -f2`
test $var1 -eq 2 -a $var2 -ge 6 && echo $kernel || echo "當前核心版本不符合要求"
或者
[ $var1 -eq 2 -a $var2 -ge 6 ] && echo $kernel || echo "當前核心版本不符合要求"
或者
[[ $var1 -eq 2 && $var2 -ge 6 ]] && echo $kernel || echo "當前核心版本不符合要求"
或者
#!/bin/bash
kernel=`uname -r`
test ${kernel:0:1} -eq 2 -a ${kernel:2:1} -ge 6 && echo $kernel || echo '不符合要求'
其他命令參考:
uname -r|grep ^2.[6-9] || echo '不符合要求'
相關文章
- shell程式設計(五)條件判斷程式設計
- 『忘了再學』Shell流程控制 — 34、if條件判斷語句(二)
- 『忘了再學』Shell流程控制 — 33、if條件判斷語句(一)
- C++ 條件與 If 語句:掌握邏輯判斷與流程控制精髓C++
- 六、Vue條件判斷Vue
- Grovvy-條件判斷
- 12.python流程控制之if判斷Python
- lisp 裡的條件判斷Lisp
- Shell 條件判斷總結
- Java雜記3—流程控制之條件Java
- 程式碼優化-多型代替IF條件判斷優化多型
- shell程式設計中的控制判斷語句程式設計
- PbootCMS判斷有無子選單各種條件判斷和標籤boot
- PbootCMS奇偶數判斷(隔行變色)各種條件判斷和標籤boot
- PbootCMS整理分頁判斷進階各種條件判斷和標籤boot
- thinkphp-條件判斷-範圍判斷-range標籤PHP
- 蝦扯蛋之條件判斷的極致優化優化
- Laravel 5 判斷條件是否存在Laravel
- mysql 插入時帶判斷條件MySql
- python3.0 -條件判斷Python
- shell程式設計之條件語句程式設計
- 人人都能學會的python程式設計教程8:條件判斷與迴圈Python程式設計
- PbootCMS整理判斷是否連結賦值各種條件判斷和標籤boot賦值
- PbootCMS導航欄 logo 居中判斷各種條件判斷和標籤bootGo
- shell指令碼中的運算子和條件判斷指令碼
- PbootCMS判斷第一個迴圈項,並新增 class條件判斷和標籤boot
- python條件判斷與迴圈Python
- MySQL函式-條件判斷函式MySql函式
- thinkphp-條件判斷-if標籤2PHP
- 條件註釋判斷瀏覽器瀏覽器
- 02 shell程式設計之條件語句程式設計
- 易優CMS模板標籤if條件判斷多層次判斷
- Python的流程控制-if條件Python
- PbootCMS判斷標籤為空時不顯示各種條件判斷和標籤boot
- PbootCMS判斷導航從第幾個開始各種條件判斷和標籤boot
- 條件註釋判斷瀏覽器版本瀏覽器
- Python基礎:條件判斷 & 迴圈Python
- Go的條件判斷語句的使用Go