十六週三次課

一、 shell腳本中的邏輯判斷

Shell腳本的if語句、循環語句中都會有一個邏輯判斷式。邏輯判斷式用於各類條件的判斷,除非程序是流水帳,不然是必定會用到邏輯判斷的,可見其重要性。linux

Shell的邏輯判斷,我目前所知共有兩種:shell

一、test命令,能夠結合命令執行結果變量($?)或者&&以及||來實現不一樣條件走不一樣分支bash

二、[ 條件判斷 ],這種方式經常使用於if語句和while語句中less

shell中的邏輯判斷 
格式1:if 條件 ; then 語句; fi 
格式2:if 條件; then 語句; else 語句; fi 
格式3:if …; then … ;elif …; then …; else …; fi 
邏輯判斷表達式:if [ $a -gt $b ]; if [ $a -lt 5 ]; if [ $b -eq 10 ]等 -gt (>); -lt(<); -ge(>=); -le(<=);-eq(==); -ne(!=) 注意處處都是空格 
可使用 && || 結合多個條件 
if [ $a -gt 5 ] && [ $a -lt 10 ]; then 
if [ $b -gt 5 ] || [ $b -lt 3 ]; then測試

#!/bin/bash
# author:菜鳥教程
# url:www.runoob.com

a=10
b=20

if [ $a -eq $b ]
then
   echo "$a -eq $b : a 等於 b"
else
   echo "$a -eq $b: a 不等於 b"
fi
if [ $a -ne $b ]
then
   echo "$a -ne $b: a 不等於 b"
else
   echo "$a -ne $b : a 等於 b"
fi
if [ $a -gt $b ]
then
   echo "$a -gt $b: a 大於 b"
else
   echo "$a -gt $b: a 不大於 b"
fi
if [ $a -lt $b ]
then
   echo "$a -lt $b: a 小於 b"
else
   echo "$a -lt $b: a 不小於 b"
fi
if [ $a -ge $b ]
then
   echo "$a -ge $b: a 大於或等於 b"
else
   echo "$a -ge $b: a 小於 b"
fi
if [ $a -le $b ]
then
   echo "$a -le $b: a 小於或等於 b"
else
   echo "$a -le $b: a 大於 b"
fi

10 -eq 20: a 不等於 b 
10 -ne 20: a 不等於 b 
10 -gt 20: a 不大於 b 
10 -lt 20: a 小於 b 
10 -ge 20: a 小於 b 
10 -le 20: a 小於或等於 bui

 

參數url

功能spa

說明.net

-e命令行

文件是否存在

對文件類型的判斷

test -e file

-f

判斷文件名是否存在且爲文件

-d

判斷文件名是否存在且爲目錄

-r

判斷對該文件是否有「可讀」權限

對文件權限的檢測

test -r file

-w

判斷對該文件是否有「可寫」權限

-x

判斷對該文件是否有「可執行」權限

-nt

(newer than)判斷file1是否比file2新

兩個文件之間的比較

test file1 -nt file2

-ot

(older than)判斷file1是否比file2舊

-ef

判斷file1和file2是否爲同一文件

-eq

兩數值是否相等(equal)

兩個整數之間的比較

test n1 -eq n2

-ne

兩數值是否不等(not equal)

-gt

n1大於n2(greater than)

-lt

n1小於n2(less than)

-ge

n1大於等於n2(greater than or equal)

-le

n1小於等於n2(less than or equal)

test -z string

判斷字符串是否爲空,若是爲空,則爲true

字符串的判斷

對參與判斷的字符串,最好加上""",如"$var"這樣的格式,否則會產生「參數過多」的錯

判斷相等的時候,"="和"=="是等效的

test -n string

判斷字符串是否爲空,若是爲空,則返回false

test str1=str2

判斷str1是否等於str2,若相等,則返回true

test str1!=str2

判斷str1是否不等於str2,若相等,則返回false

-a

兩個條件同時成立則爲真

test -r file1 -a test -x file2

多重條件的判斷

 

-o

兩個條件任意一個成立則爲真

test -r file1 -a test -x file2

!

對測試條件結果取反

test ! -x file

這是一些經常使用的test命令的參數,「[]」的用法與test命令相似,只要去掉test這個命令就行,其他不變。

運算符號 表明意義
= 等於 應用於:整型或字符串比較 若是在[] 中,只能是字符串
!= 不等於 應用於:整型或字符串比較 若是在[] 中,只能是字符串
< 小於 應用於:整型比較 在[] 中,不能使用 表示字符串
> 大於 應用於:整型比較 在[] 中,不能使用 表示字符串
-eq 等於 應用於:整型比較
-ne 不等於 應用於:整型比較
-lt 小於 應用於:整型比較
-gt 大於 應用於:整型比較
-le 小於或等於 應用於:整型比較
-ge 大於或等於 應用於:整型比較
-a 雙方都成立(and) 邏輯表達式 –a 邏輯表達式
-o 單方成立(or) 邏輯表達式 –o 邏輯表達式
-z 空字符串
-n 非空字符串

 

關於&&和||

用&&和||結合多個條件

例如1:

[root@localhost shell]# cat if4.sh 

#/bin/bash

a=5

if [ $a -gt 4 ] && [ $a -lt 6 ]

then

   echo "4<a<6"

else

   echo nook

fi

[root@localhost shell]# sh if4.sh 

4<a<6

這個是用於聯合兩個命令的,邏輯與(&&)和邏輯或(||),在if和循環的判斷式中的意義與C語言中是同樣的。

邏輯與:表示兩個同時爲真,則改表達式爲真,不然爲假。

邏輯或:表示任意一個爲真,則表達式爲真,不然爲假。

 

可是在test命令中,這兩個操做符的意義有所 不一樣

 

命令格式

解釋
cmd1 && cmd2

若cmd1執行完畢且正確執行($?=0),則開始執行cmd2

若cmd1執行完畢且返回出錯($?≠0),則不執行cmd2

cmd1 || cmd2

若cmd1執行完畢且正確執行($?=0),則不執行cmd2

若cmd1執行完畢且返回出錯($?≠0),則執行cmd2

若是是多於兩個命令的聯合,執行結果會不斷的日後傳,影響後面的判斷。同時由於$?只有一個,因此這個影響有個就近原則。

 


二、 文件目錄屬性判斷

 

格式1:if條件;then語句;fi        (若是...而後...)

例如:

[root@localhost shell]# cat if1.sh 

#/bin/bash

a=3

if [ $a -gt 1 ]

then

   echo ok

fi

結果:

[root@localhost shell]# sh if1.sh 

ok

 

格式2:if條件;then語句;else語句;fi        (若是...而後...;不知足條件...而後....)

示列:

[root@localhost shell]# cat if2.sh 

#/bin/bash

a=1

if [ $a -gt 3 ]

then

   echo ok

else

   echo no ok

fi

結果:

[root@localhost shell]# sh if2.sh 

nook

 

格式3:if...;then...;elif...;then...;else...;fi (若是...而後...;還有...而後...,不知足條件...而後...)

(能夠添加多個elif)

例如:

[root@congji shell]# cat if3.sh 

#/bin/bash

a=*

if [ $a -gt 6 ]

then

   echo "a > 3"

elif

   [ $a -lt 9 ]

then

   echo "< 9"

else

   echo no ok

fi

 

當a等於5時

[root@localhost shell]# sh if3.sh 

< 9

當a等於7時

[root@localhost shell]# sh if3.sh 

a > 3

因此當if知足條件,elif不會執行

 

test 命令 

使用方法:test EXPRESSION 

如: 


[root@localhost ~]# test 1 = 1 && echo 'ok' 
ok 
[root@localhost ~]# test -d /etc/ && echo 'ok' 
ok 
[root@localhost ~]# test 1 -eq 1 && echo 'ok' 
ok 
[root@localhost ~]# if test 1 = 1 ; then echo 'ok'; fi 

 

精簡表達式 


[] 表達式 
[root@localhost ~]# [ 1 -eq 1 ] && echo 'ok' 
ok 
[root@localhost ~]# [ 2 < 1 ] && echo 'ok' 
-bash: 2: No such file or directory 
[root@localhost ~]# [ 2 \< 1 ] && echo 'ok' 
[root@localhost ~]# [ 2 -gt 1 -a 3 -lt 4 ] && echo 'ok' 
ok 
[root@localhost ~]# [ 2 -gt 1 && 3 -lt 4 ] && echo 'ok' 
-bash: [: missing `]' 

注意:在[] 表達式中,常見的>,<須要加轉義字符,表示字符串大小比較,以acill碼 位置做爲比較。 不直接支持<>運算符,還有邏輯運算符|| && 它須要用-a[and] –o[or]表示 

 

[[]] 表達式 


[root@localhost ~]# [ 1 -eq 1 ] && echo 'ok' 
ok 
[root@localhost ~]$ [[ 2 < 3 ]] && echo 'ok' 
ok 
[root@localhost ~]$ [[ 2 < 3 && 4 > 5 ]] && echo 'ok' 
ok 



注意:[[]] 運算符只是[]運算符的擴充。可以支持<,>符號運算不須要轉義符,它仍是以字符串比較大小。裏面支持邏輯運算符:|| && 

 

注意:全部字符 與邏輯運算符直接用「空格」分開,不能連到一塊兒。 


三、 if特殊用法(經常使用)

(1). if [ -z "$a" ]  這個表示當變量a的值爲空時會怎麼樣 ,例如我如今須要獲取一個文件內容的行數賦值給一個變量,而後把這個變量做爲判斷條件,可是我不肯定這個文件會否存在,因此我得先判斷這個變量是否爲空,爲空則要打印錯誤。

if 判斷文件、目錄屬性 
[ -f file ]判斷是不是普通文件,且存在 
[ -d file ] 判斷是不是目錄,且存在 
[ -e file ] 判斷文件或目錄是否存在 
[ -r file ] 判斷文件是否可讀 
[ -w file ] 判斷文件是否可寫 
[ -x file ] 判斷文件是否可執行

esle if和elif,是同樣的

判斷是否爲目錄時,else後是mkdir $d

#!/bin/bash
# author:菜鳥教程
# url:www.runoob.com

file="/var/www/runoob/test.sh"
if [ -r $file ]
then
   echo "文件可讀"
else
   echo "文件不可讀"
fi
if [ -w $file ]
then
   echo "文件可寫"
else
   echo "文件不可寫"
fi
if [ -x $file ]
then
   echo "文件可執行"
else
   echo "文件不可執行"
fi
if [ -f $file ]
then
   echo "文件爲普通文件"
else
   echo "文件爲特殊文件"
fi
if [ -d $file ]
then
   echo "文件是個目錄"
else
   echo "文件不是個目錄"
fi
if [ -s $file ]
then
   echo "文件不爲空"
else
   echo "文件爲空"
fi
if [ -e $file ]
then
   echo "文件存在"
else
   echo "文件不存在"
fi

文件可讀 
文件可寫 
文件可執行 
文件爲普通文件 
文件不是個目錄 
文件不爲空 
文件存在

if判斷的一些特殊用法 
if [ -z 「$a」 ] 這個表示當變量a的值爲空時會怎麼樣 ,判斷變量是否存在。
if [ -n 「$a」 ] 表示當變量a的值不爲空 
if grep -q ‘123’ 1.txt; then 表示若是1.txt中含有’123’的行時會怎麼樣 
if [ ! -e file ]; then 表示文件不存在時會怎麼樣 
if (($a<1)); then …等同於 if [ $a -lt 1 ]; then… 
[ ] 中不能使用<,>,==,!=,>=,<=這樣的符號

=:是賦值;==:是等於號

不管是-n仍是-z,都不能做用在文件上。只能做用於變量。

#!/bin/bash
# author:菜鳥教程
# url:www.runoob.com

a="abc"
b="efg"

if [ $a = $b ]
then
   echo "$a = $b : a 等於 b"
else
   echo "$a = $b: a 不等於 b"
fi
if [ $a != $b ]
then
   echo "$a != $b : a 不等於 b"
else
   echo "$a != $b: a 等於 b"
fi
if [ -z $a ]
then
   echo "-z $a : 字符串長度爲 0"
else
   echo "-z $a : 字符串長度不爲 0"
fi
if [ -n $a ]
then
   echo "-n $a : 字符串長度不爲 0"
else
   echo "-n $a : 字符串長度爲 0"
fi
if [ $a ]
then
   echo "$a : 字符串不爲空"
else
   echo "$a : 字符串爲空"
fi
abc = efg: a 不等於 b
abc != efg : a 不等於 b
-z abc : 字符串長度不爲 0
-n abc : 字符串長度不爲 0
abc : 字符串不爲空

shell中的case判斷 
格式 case 變量名 in 
value1) 
command 
;; 
value2) 
command 
;; 
*) 
commond 
;; 
esac 
在case程序中,能夠在條件中使用|,表示或的意思, 好比 2|3) command ;;

實例:

查詢指定的文件是否存在,不存在,就touch建立出現了

只須要把echo後面的$,換成你須要的,-d,-e,-r,-o等等

!vi命令:執行是一個vi編輯的文件。!sh命令:執行上一個sh執行的文件,也就是sh 3.sh

判斷1.sh是否爲空,爲空輸出ok.變量要用雙引號引發來。文件就不用了。

判斷$b的值是否爲空,爲空輸出$b.不爲空,輸出b is null。

若是這個文件不存在

#!/bin/bash

f="/tmp/aminglinux"

[ -f $f ] || touch $f       #若是上面的目錄不存在,就touch建立他

if [ ! -f $f ]          #前面添加一個歎號,取相反的意思,-f是存在的意思, ! -f是不存在

then

      touch $f                         #touch能夠

fi

 

[ -f $f ] && rm -f $f

等於

if [ -f $f]

then

       rm -f $f

fi

 

 if特殊用法

#!/bin/bash

n='wc -l /tmp/local'

if [ $n -gt 100 ]               #統計文件大於100行

then 

       echo sdahd

fi 


四、case判斷 

-n STRING

              the length of STRING is nonzero

 

       STRING equivalent to -n STRING

 

       -z STRING

              the length of STRING is zero

 

-n  判斷字符串是否不爲零

-z 判斷字符串是否爲零 

tar 0是爲了提示你輸入的範圍不在0-100之內;須要告訴用戶。

 

咱們在介紹case這個命令以前,先解釋一個read -p命令。

咱們先用命令行來測試一下這個命令。

[root@localhost ~]# read -p "Please input a number: " n

Please input a number: 123

[root@localhost~]# echo $n

123

 

經過上面的實驗咱們能夠發現,read -p 能夠和用戶實現一個交互,並賦給變量一個值。

 

 

刪除筆記修改筆記

咱們等會寫一個關於case的腳本。咱們把它分紅2部分來解析。首先看第一部分:

#/bin/bash

read -p "Please input a number: " n

if [ -z "$n" ]

then

    echo "Please input a number."

    exit 1

fi

首先,咱們讓用戶輸入一個數字,-z表示,若是變量爲空,那麼會返回一個Please input a number的字符串,而且exit退出,=。

還記得咱們編譯時,若是失敗了,當咱們用echo !$查詢時,發現返回值爲1,這裏的1就是這個意思。

 

n1=`echo $n|sed 's/[0-9]//g'`

if [ -n "$n1" ]

then

 echo "Please input a number."

 exit 1

fi

 

若是用戶輸入的值不爲空,那麼跳入這一步,首先會把用戶輸入的變量拿出來,作一個過濾,sed命令把全部數字所有清空,-n表示若是sed清空數字後,字符不爲空,則表示用戶輸入了一個不是數字的字符,則會返回,Please input a number!,這裏加一個!和上面的作區分。

 

執行結果:

[root@localhost shell]# sh case1.sh 

Please input a number: 

Please input a number.

 

[root@localhost shell]# sh case1.sh 

Please input a number: ds1

Please input a number!!

第二部分:使用了if...then...;elif...then...;eles....

若是變量是n大於等於0,小於等於60,則變量tag=1。

若是變量n大於等於60,小於等於80,則變量tag=2。

若是變量n大於等於80,小於等於90,則變量tag=3。

若是變量n大於等於90,小於等於100,則變量tag=4。

 

if [ $n -lt 60 ] && [ $n -ge 0 ]                 

then

    tag=1

elif [ $n -ge 60 ] && [ $n -lt 80 ]

then

    tag=2

elif [ $n -ge 80 ]  && [ $n -lt 90 ]

then

    tag=3

elif [ $n -ge 90 ] && [ $n -le 100 ]

then

    tag=4

else

    tag=0

fi

 

第三部分,就是咱們要說的case循環了.注意格式,case 變量 in ,1)...;; 2)...;; 3)...;;,最後結尾用esac,咱們也能夠|來表示並列,例如,3|4),就是當變量等於3或者4時,返回下面的命令。

 

當變量tag=1時,返回not ok

當變量tag=2時,返回ok

當變量tag=3時,返回ook

當變量tag=4時,返回oook

當變量等於其餘時,說明用戶輸入的值不在這個範圍內,則返回值"The number range is 0-100."

case $tag in

    1)

        echo "not ok"

        ;;

    2)

        echo "ok"

        ;;

    3)

        echo "ook"

        ;;

    4)

        echo "oook"

        ;;

    *)

        echo "The number range is 0-100."

        ;;

esac

 

注意:

判斷$a是否爲文件,不是的話就touch,後來改爲判斷$a是否爲目錄,不是的話仍是touch一下,接着您就判斷$a是否存在,不存在的話仍是touch一下。

正確邏輯應該是 mkdir

2.echo $?在腳本中須要放在exit以前?

echo $? 不須要放在腳本中的

 

常見問題:判斷$a是否爲文件,不是的話就touch,後來改爲判斷$a是否爲目錄,不是的話仍是touch一下,接着您就判斷$a是否存在,不存在的話仍是touch一下。正確邏輯應該是 mkdir

二、出現參數太多    這個文件存在 -n  就不出現參數太多

答:先運行  wc -l /tmp/gao 看看結果

你比較的是一個數字,而不是 「數字  文件名」, n=`wc -l /tmp/gao|sed 's/[^0-9]//g'` 沒有報錯.

三、[ if -n ] 和 [ if -z ] 對文件判斷是否爲空並沒用有 

如圖 "若是 999文件不爲空, 則ok", 但我並無999文件

答:經證明,不管是-n仍是-z,都不能做用在文件上。只能做用於變量。

 

比較連接:https://blog.csdn.net/lovektm/article/details/79275375

相關文章
相關標籤/搜索