shell編程(二)

一、條件判斷語法結構
條件判斷相關參數
1)判斷文件類型
2)判斷文件權限
3)判斷文件新舊
4)判斷整數
5)判斷字符串
6)多重條件判斷
二、流程控制語句
基本語法結構
1)if結構
2)if...else結構
3)if...elif...else結構
4)層層嵌套結構
應用案例
1)判斷兩臺主機是否ping通
2)判斷一個進程是否存在
3)判斷一個服務是否正常
4)判斷用戶是否存在
5)判斷軟件包是否安裝
6)判斷當前主機的內

一、條件判斷語法結構

思考:何爲真(==true==)?何爲假(==false==)?

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

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

特別說明:

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

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

3)  更多判斷,`man test`去查看,很多的參數都用來進行條件判斷

2. 條件判斷相關參數

1)判斷文件類型

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

舉例說明:

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

2)判斷文件權限

判斷參數 含義
-r 當前用戶對其是否可讀
-w 當前用戶對其是否可寫
-x 當前用戶對其是否可執行
-u 是否有suid,高級權限冒險位
-g 是否sgid,高級權限強制位
-k 是否有t位,高級權限粘滯位

3)判斷文件新舊

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

判斷參數 含義
file1 -nt file2 比較file1是否比file2新
file1 -ot file2 比較file1是否比file2舊
file1 -ef file2 比較是否爲同一個文件,或者用於判斷硬連接,是否指向同一個inode

4)判斷整數

判斷參數 含義
-eq 相等
-ne 不等
-gt 大於
-lt 小於
-ge 大於等於
-le 小於等於

5)判斷字符串

判斷參數 含義
-z 判斷是否爲==空==字符串,字符串長度爲0則成立
-n 判斷是否爲==非空==字符串,字符串長度不爲0則成立
string1 = string2 判斷字符串是否相等
string1 != string2 判斷字符串是否相不等

6)多重條件判斷

判斷符號 含義 舉例
-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. 符號;和&&和||都可以用來分割命令或者表達式
2. 分號(;)完全不考慮前面的語句是否正確執行,都會執行;號後面的內容
3. `&&`符號,需要考慮&&前面的語句的正確性,前面語句正確執行纔會執行&&後的內容;反之亦然
4. `||`符號,需要考慮||前面的語句的非正確性,前面語句執行錯誤纔會執行||後內容;反之亦然
5. 如果&&和||一起出現,從左往右依次看,按照以上原則

二、流程控制語句

1. 基本語法結構

1)if結構

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

==T==:表示true,爲真

if [ condition ];then
        command
        command
fi

if test 條件;then
    命令
fi

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

[ 條件 ] && command

shell編程(二)

2)if...else結構

if [ condition ];then
        command1
    else
        command2
fi

[ 條件 ] && command1 || command2

shell編程(二)

小試牛刀:

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

  1. read定義變量
  2. if....else...
#!/bin/env bash
read -p '請輸入一個字符串:' str
if [ "$str" = 'hello' ];then
    echo 'world'
 else
    echo '請輸入hello!'
fi
或者
#!/bin/env bash
A=hello
B=world

if [ "$1" = "$A" ];then
        echo "$B"
    else
        echo "$A"
fi
或者
read -p '請輸入一個字符串:' str;
 [ "$str" = 'hello' ] && echo 'world' ||  echo '請輸入hello!'

3)if...elif...else結構

if [ condition1 ];then
        command1    結束
    elif [ condition2 ];then
        command2    結束
    else
        command3
fi
註釋:
如果條件1滿足,執行命令1後結束;如果條件1不滿足,再看條件2,如果條件2滿足執行命令2後結束;如果條件1和條件2都不滿足執行命令3結束.

shell編程(二)

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

shell編程(二)

2. 應用案例

1)判斷兩臺主機是否ping通

需求:判斷==當前主機==是否和==遠程主機==是否ping通

① 思路

  1. 使用哪個命令實現 ping -c次數
  2. 根據命令的==執行結果狀態==來判斷是否通$?
  3. 根據邏輯和語法結構來編寫腳本(條件判斷或者流程控制)

② 落地實現

#!/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不通的"

2)判斷一個進程是否存在

需求:判斷web服務器中httpd進程是否存在

① 思路

  1. 查看進程的相關命令 ps pgrep
  2. 根據命令的返回狀態值來判斷進程是否存在
  3. 根據邏輯用腳本語言實現

② 落地實現

#!/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。

3)判斷一個服務是否正常

需求:判斷門戶網站是否能夠正常訪問

① 思路

  1. 可以判斷進程是否存在,用/etc/init.d/httpd status判斷狀態等方法
  2. 最好的方法是==直接去訪問==一下,通過訪問成功和失敗的返回值來判斷
    • 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,請立刻處理"

4)判斷用戶是否存在

需求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 '不存在'

5)判斷軟件包是否安裝

需求2:用腳本判斷一個軟件包是否安裝,如果沒安裝則安裝它(假設本地yum已配合)

6)判斷當前主機的內核版本

需求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 '不符合要求'

————————————本文到此結束,感謝閱讀—————————————

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章