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
注意:[[]] 運算符只是[]運算符的擴充。可以支持<,>符號運算不須要轉義符,它仍是以字符串比較大小。裏面支持邏輯運算符:|| &&
注意:全部字符 與邏輯運算符直接用「空格」分開,不能連到一塊兒。
(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能夠
[ -f $f ] && rm -f $f
if [ -f $f]
rm -f $f
fi
if特殊用法
#!/bin/bash
n='wc -l /tmp/local'
if [ $n -gt 100 ] #統計文件大於100行
then
echo sdahd
fi
-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