03_SHELL編程之條件判斷和流程控制

本節(jié)課程目標(biāo)

  • 熟悉條件判斷語句颓哮,如判斷整數(shù)磕洪、判斷字符串等
  • 熟悉流程控制語句基本語法,如if…else…

一威创、條件判斷語法結(jié)構(gòu)

思考:何為真(==true==)落午?何為假(==false==)?

1. ==條件判斷語法格式==

  • 格式1: ==test== 條件表達(dá)式
  • 格式2: [ 條件表達(dá)式 ]
  • 格式3: [[ 條件表達(dá)式 ]] 支持正則 =~

特別說明:

1)==[== 親親肚豺,我兩邊都有空格溃斋,不空打死你呦 ==]== :imp:

2)==[[== 親親,我兩邊都有空格吸申,不空打死你呦 ==]]==:imp:

  1. 更多判斷梗劫,man test去查看,很多的參數(shù)都用來進(jìn)行條件判斷

2. 條件判斷相關(guān)參數(shù)

問:你要判斷什么截碴?

答:我要判斷文件類型梳侨,判斷文件新舊,判斷字符串是否相等日丹,判斷權(quán)限等等...

㈠ ==判斷文件類型==

判斷參數(shù) 含義
==-e== 判斷文件是否存在(任何類型文件)
-f 判斷文件是否存在==并且==是一個普通文件
-d 判斷文件是否存在并且是一個目錄
-L 判斷文件是否存在并且是一個軟連接文件
-b 判斷文件是否存在并且是一個塊設(shè)備文件
-S 判斷文件是否存在并且是一個套接字文件
-c 判斷文件是否存在并且是一個字符設(shè)備文件
-p 判斷文件是否存在并且是一個命名管道文件
==-s== 判斷文件是否存在并且是一個非空文件(有內(nèi)容)

舉例說明:

test -e file                    只要文件存在條件為真
[ -d /shell01/dir1 ]            判斷目錄是否存在走哺,存在條件為真
[ ! -d /shell01/dir1 ]      判斷目錄是否存在,不存在條件為真
[[ -f /shell01/1.sh ]]      判斷文件是否存在,并且是一個普通的文件

㈡ 判斷文件權(quán)限

判斷參數(shù) 含義
-r 當(dāng)前用戶對其是否可讀
-w 當(dāng)前用戶對其是否可寫
-x 當(dāng)前用戶對其是否可執(zhí)行
-u 是否有suid哲虾,高級權(quán)限冒險位
-g 是否sgid割坠,高級權(quán)限強制位
-k 是否有t位,高級權(quán)限粘滯位

㈢ 判斷文件新舊

說明:這里的新舊指的是==文件的修改時間==妒牙。

判斷參數(shù) 含義
file1 -nt file2 比較file1是否比file2新
file1 -ot file2 比較file1是否比file2舊
file1 -ef file2 比較是否為同一個文件彼哼,或者用于判斷硬連接,是否指向同一個inode

㈣ 判斷整數(shù)

判斷參數(shù) 含義
-eq 相等
-ne 不等
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于

㈤ ==判斷字符串==

判斷參數(shù) 含義
-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 ]

==特別說明:==

&& 前面的表達(dá)式==為真==,才會執(zhí)行后面的代碼

|| 前面的表達(dá)式==為假==,才會執(zhí)行后面的代碼

; ==只==用于==分割==命令或表達(dá)式

① 舉例說明

  • 數(shù)值比較
[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風(fēng)格的數(shù)值比較
注意:在(( ))中拴签,=表示賦值孝常;==表示判斷
[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  表達(dá)式
[ 表達(dá)式 ]
[[ 表達(dá)式 ]]

思考:[ ] 和 [[ ]] 有什么區(qū)別构灸?

[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 $?

② 邏輯運算符總結(jié)

  1. 符號;和&&和||都可以用來分割命令或者表達(dá)式
  2. 分號(;)完全不考慮前面的語句是否正確執(zhí)行,都會執(zhí)行;號后面的內(nèi)容
  3. &&符號岸梨,需要考慮&&前面的語句的正確性喜颁,前面語句正確執(zhí)行才會執(zhí)行&&后的內(nèi)容;反之亦然
  4. ||符號曹阔,需要考慮||前面的語句的非正確性半开,前面語句執(zhí)行錯誤才會執(zhí)行||后內(nèi)容;反之亦然
  5. 如果&&和||一起出現(xiàn)赃份,從左往右依次看寂拆,按照以上原則

二、流程控制語句

關(guān)鍵詞:==選擇==(人生漫漫長路抓韩,我該何去何從:vertical_traffic_light:)

1. 基本語法結(jié)構(gòu)

㈠ ==if結(jié)構(gòu)==

箴言1:只要正確纠永,就要一直向前沖:v:

==F==:表示false,為假

==T==:表示true谒拴,為真

if [ condition ];then
        command
        command
fi

if test 條件;then
    命令
fi

if [[ 條件 ]];then
    命令
fi

[ 條件 ] && command
流程判斷1.png

㈡ ==if...else結(jié)構(gòu)==

箴言2:分叉路口渺蒿,二選一

if [ condition ];then
        command1
    else
        command2
fi

[ 條件 ] && command1 || command2
流程判斷2.png

小試牛刀:

==讓用戶自己輸入==字符串,==如果==用戶輸入的是hello彪薛,請打印world,==否則==打印“請輸入hello”

  1. read定義變量
  2. 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 "該腳本需要傳遞參數(shù)"
  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結(jié)構(gòu)==

箴言3:選擇很多怠蹂,能走的只有一條

if [ condition1 ];then
        command1    結(jié)束
    elif [ condition2 ];then
        command2    結(jié)束
    else
        command3
fi
注釋:
如果條件1滿足善延,執(zhí)行命令1后結(jié)束;如果條件1不滿足城侧,再看條件2易遣,如果條件2滿足執(zhí)行命令2后結(jié)束;如果條件1和條件2都不滿足執(zhí)行命令3結(jié)束.
流程判斷3.png

㈣ 層層嵌套結(jié)構(gòu)

箴言4:多次判斷嫌佑,帶你走出人生迷霧豆茫。

if [ condition1 ];then
        command1        
        if [ condition2 ];then
            command2
        fi
 else
        if [ condition3 ];then
            command3
        elif [ condition4 ];then
            command4
        else
            command5
        fi
fi
注釋:
如果條件1滿足,執(zhí)行命令1屋摇;如果條件2也滿足執(zhí)行命令2揩魂,如果不滿足就只執(zhí)行命令1結(jié)束;
如果條件1不滿足炮温,不看條件2火脉;直接看條件3,如果條件3滿足執(zhí)行命令3;如果不滿足則看條件4倦挂,如果條件4滿足執(zhí)行命令4畸颅;否則執(zhí)行命令5
流程判斷4.png

2. 應(yīng)用案例

㈠ 判斷兩臺主機(jī)是否ping通

需求:判斷==當(dāng)前主機(jī)==是否和==遠(yuǎn)程主機(jī)==是否ping通

① 思路

  1. 使用哪個命令實現(xiàn) ping -c次數(shù)
  2. 根據(jù)命令的==執(zhí)行結(jié)果狀態(tài)==來判斷是否通$?
  3. 根據(jù)邏輯和語法結(jié)構(gòu)來編寫腳本(條件判斷或者流程控制)

② 落地實現(xiàn)

#!/bin/env bash
# 該腳本用于判斷當(dāng)前主機(jī)是否和遠(yuǎn)程指定主機(jī)互通

# 交互式定義變量,讓用戶自己決定ping哪個主機(jī)
read -p "請輸入你要ping的主機(jī)的IP:" ip

# 使用ping程序判斷主機(jī)是否互通
ping -c1 $ip &>/dev/null

if [ $? -eq 0 ];then
    echo "當(dāng)前主機(jī)和遠(yuǎn)程主機(jī)$ip是互通的"
 else
    echo "當(dāng)前主機(jī)和遠(yuǎn)程主機(jī)$ip不通的"
fi

邏輯運算符
test $? -eq 0 &&  echo "當(dāng)前主機(jī)和遠(yuǎn)程主機(jī)$ip是互通的" || echo "當(dāng)前主機(jī)和遠(yuǎn)程主機(jī)$ip不通的"

㈡ 判斷一個進(jìn)程是否存在

需求:判斷web服務(wù)器中httpd進(jìn)程是否存在

① 思路

  1. 查看進(jìn)程的相關(guān)命令 ps pgrep
  2. 根據(jù)命令的返回狀態(tài)值來判斷進(jìn)程是否存在
  3. 根據(jù)邏輯用腳本語言實現(xiàn)

② 落地實現(xiàn)

#!/bin/env bash
# 判斷一個程序(httpd)的進(jìn)程是否存在
pgrep httpd &>/dev/null
if [ $? -ne 0 ];then
    echo "當(dāng)前httpd進(jìn)程不存在"
else
    echo "當(dāng)前httpd進(jìn)程存在"
fi

或者
test $? -eq 0 && echo "當(dāng)前httpd進(jìn)程存在" || echo "當(dāng)前httpd進(jìn)程不存在"

③ 補充命令

pgrep命令:以名稱為依據(jù)從運行進(jìn)程隊列中查找進(jìn)程方援,并顯示查找到的進(jìn)程id
選項
-o:僅顯示找到的最忻怀础(起始)進(jìn)程號;
-n:僅顯示找到的最大(結(jié)束)進(jìn)程號;
-l:顯示進(jìn)程名稱犯戏;
-P:指定父進(jìn)程號送火;pgrep -p 4764  查看父進(jìn)程下的子進(jìn)程id
-g:指定進(jìn)程組;
-t:指定開啟進(jìn)程的終端笛丙;
-u:指定進(jìn)程的有效用戶ID漾脂。

㈢ 判斷一個服務(wù)是否正常

需求:判斷門戶網(wǎng)站是否能夠正常訪問

① 思路

  1. 可以判斷進(jìn)程是否存在,用/etc/init.d/httpd status判斷狀態(tài)等方法
  2. 最好的方法是==直接去訪問==一下胚鸯,通過訪問成功和失敗的返回值來判斷
    • Linux環(huán)境骨稿,==wget== curl elinks -dump

② 落地實現(xiàn)

#!/bin/env bash
# 判斷門戶網(wǎng)站是否能夠正常提供服務(wù)

#定義變量
web_server=www.itcast.cn
#訪問網(wǎng)站
wget -P /shell/ $web_server &>/dev/null
[ $? -eq 0 ] && echo "當(dāng)前網(wǎng)站服務(wù)是ok" && rm -f /shell/index.* || echo "當(dāng)前網(wǎng)站服務(wù)不ok,請立刻處理"

3. 課堂練習(xí)

㈠ 判斷用戶是否存在

需求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"已經(jīng)存在
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:用腳本判斷一個軟件包是否安裝哥桥,如果沒安裝則安裝它(假設(shè)本地yum已配合)


㈢ 判斷當(dāng)前主機(jī)的內(nèi)核版本

需求3:判斷當(dāng)前內(nèi)核主版本是否為2辙浑,且次版本是否大于等于6;如果都滿足則輸出當(dāng)前內(nèi)核版本

思路:
1. 先查看內(nèi)核的版本號    uname -r
2. 先將內(nèi)核的版本號保存到一個變量里拟糕,然后再根據(jù)需求截取出該變量的一部分:主版本和次版本
3. 根據(jù)需求進(jìn)步判斷


#!/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 "當(dāng)前內(nèi)核版本不符合要求"
或者
[ $var1 -eq 2 -a $var2 -ge 6 ] && echo $kernel || echo "當(dāng)前內(nèi)核版本不符合要求"
或者
[[ $var1 -eq 2 && $var2 -ge 6 ]] && echo $kernel || echo "當(dāng)前內(nèi)核版本不符合要求"

或者
#!/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 '不符合要求'
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末判呕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子送滞,更是在濱河造成了極大的恐慌侠草,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,627評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件犁嗅,死亡現(xiàn)場離奇詭異边涕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)褂微,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,180評論 3 399
  • 文/潘曉璐 我一進(jìn)店門功蜓,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人宠蚂,你說我怎么就攤上這事式撼。” “怎么了求厕?”我有些...
    開封第一講書人閱讀 169,346評論 0 362
  • 文/不壞的土叔 我叫張陵端衰,是天一觀的道長叠洗。 經(jīng)常有香客問我,道長旅东,這世上最難降的妖魔是什么灭抑? 我笑而不...
    開封第一講書人閱讀 60,097評論 1 300
  • 正文 為了忘掉前任,我火速辦了婚禮抵代,結(jié)果婚禮上腾节,老公的妹妹穿的比我還像新娘。我一直安慰自己荤牍,他們只是感情好案腺,可當(dāng)我...
    茶點故事閱讀 69,100評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著康吵,像睡著了一般劈榨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上晦嵌,一...
    開封第一講書人閱讀 52,696評論 1 312
  • 那天同辣,我揣著相機(jī)與錄音,去河邊找鬼惭载。 笑死旱函,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的描滔。 我是一名探鬼主播棒妨,決...
    沈念sama閱讀 41,165評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼含长!你這毒婦竟也來了券腔?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 40,108評論 0 277
  • 序言:老撾萬榮一對情侶失蹤拘泞,失蹤者是張志新(化名)和其女友劉穎纷纫,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體田弥,經(jīng)...
    沈念sama閱讀 46,646評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,709評論 3 342
  • 正文 我和宋清朗相戀三年铡原,在試婚紗的時候發(fā)現(xiàn)自己被綠了偷厦。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,861評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡燕刻,死狀恐怖只泼,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情卵洗,我是刑警寧澤请唱,帶...
    沈念sama閱讀 36,527評論 5 351
  • 正文 年R本政府宣布弥咪,位于F島的核電站,受9級特大地震影響十绑,放射性物質(zhì)發(fā)生泄漏聚至。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,196評論 3 336
  • 文/蒙蒙 一本橙、第九天 我趴在偏房一處隱蔽的房頂上張望扳躬。 院中可真熱鬧,春花似錦甚亭、人聲如沸贷币。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,698評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽役纹。三九已至,卻和暖如春暇唾,著一層夾襖步出監(jiān)牢的瞬間促脉,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,804評論 1 274
  • 我被黑心中介騙來泰國打工信不, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留嘲叔,地道東北人。 一個月前我還...
    沈念sama閱讀 49,287評論 3 379
  • 正文 我出身青樓抽活,卻偏偏與公主長得像硫戈,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子下硕,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,860評論 2 361