本節(jié)課程目標(biāo)
- 熟悉條件判斷語句颓哮,如判斷整數(shù)磕洪、判斷字符串等
- 熟悉流程控制語句基本語法,如if…else…
一威创、條件判斷語法結(jié)構(gòu)
思考:何為真(==true==)落午?何為假(==false==)?
1. ==條件判斷語法格式==
- 格式1: ==test== 條件表達(dá)式
- 格式2: [ 條件表達(dá)式 ]
- 格式3: [[ 條件表達(dá)式 ]] 支持正則 =~
特別說明:
1)==[== 親親肚豺,我兩邊都有空格溃斋,不空打死你呦 ==]== :imp:
2)==[[== 親親,我兩邊都有空格吸申,不空打死你呦 ==]]==:imp:
- 更多判斷梗劫,
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é)
- 符號;和&&和||都可以用來分割命令或者表達(dá)式
- 分號(;)完全不考慮前面的語句是否正確執(zhí)行,都會執(zhí)行;號后面的內(nèi)容
-
&&
符號岸梨,需要考慮&&前面的語句的正確性喜颁,前面語句正確執(zhí)行才會執(zhí)行&&后的內(nèi)容;反之亦然 -
||
符號曹阔,需要考慮||前面的語句的非正確性半开,前面語句執(zhí)行錯誤才會執(zhí)行||后內(nèi)容;反之亦然 - 如果&&和||一起出現(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
㈡ ==if...else結(jié)構(gòu)==
箴言2:分叉路口渺蒿,二選一
if [ condition ];then
command1
else
command2
fi
[ 條件 ] && command1 || command2
小試牛刀:
==讓用戶自己輸入==字符串,==如果==用戶輸入的是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 "該腳本需要傳遞參數(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é)束.
㈣ 層層嵌套結(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
2. 應(yīng)用案例
㈠ 判斷兩臺主機(jī)是否ping通
需求:判斷==當(dāng)前主機(jī)==是否和==遠(yuǎn)程主機(jī)==是否ping通
① 思路
- 使用哪個命令實現(xiàn)
ping -c次數(shù)
- 根據(jù)命令的==執(zhí)行結(jié)果狀態(tài)==來判斷是否通
$?
- 根據(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)程是否存在
① 思路
- 查看進(jìn)程的相關(guān)命令 ps pgrep
- 根據(jù)命令的返回狀態(tài)值來判斷進(jìn)程是否存在
- 根據(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)站是否能夠正常訪問
① 思路
- 可以判斷進(jìn)程是否存在,用/etc/init.d/httpd status判斷狀態(tài)等方法
- 最好的方法是==直接去訪問==一下胚鸯,通過訪問成功和失敗的返回值來判斷
- 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 '不符合要求'