linux的逻辑运算参数,Linux基础之bash脚本编程初级-逻辑运算与测试
引言
前面介紹了bash編程的基礎(chǔ)變量與算術(shù)表達式,本文介紹在腳本中的進階知識:測試
在bash中測試大體分兩部分:條件測試、組合測試。
而條件測試又分:數(shù)值測試、字符串測試、文件測試。
組合測試則有兩種表達方式。具體是什么表達方式在文章中會有具體展示。
本文實驗環(huán)境為CentOS7.2
Linux中為什么要學(xué)習(xí)測試(判斷)?
當(dāng)我第一次學(xué)習(xí)這部分內(nèi)容時,覺得好難,好不爽。可是這又是想要繼續(xù)學(xué)習(xí)Linux必須要掌握的知識點。為什么?我們在生活中面對各種選擇時總要問問自己,我是否應(yīng)該怎樣,不這樣會發(fā)生什么,在生活中就有諸多類似的“測試”,工作中也離不開,而我們學(xué)習(xí)Linux掌握這門技術(shù)是為了更好的工作,Linux的學(xué)習(xí)自然也離不開“測試”。當(dāng)然這么說還有些抽象,那么就舉個具體的例子:接受一個主機的IPv4地址做為參數(shù),測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”。
如果你沒有學(xué)過測試那么此時別人讓你寫這么一個腳本供他使用,你怎么辦?
在正式介紹測試前,我們需要先介紹下在測試中必備的數(shù)學(xué)知識:邏輯運算
邏輯運算:
邏輯運算在希臘時期就已經(jīng)出現(xiàn),不過它正式被運用于數(shù)字電路及計算機則是20世紀(jì)的一個人物:香農(nóng)。他在其碩士論文中提出將布爾代數(shù)應(yīng)用于電子領(lǐng)域的概念,并給出能夠構(gòu)建任何邏輯和數(shù)值關(guān)系的邏輯電路的解決方法。有了香農(nóng)的貢獻才有了如今的計算機。
邏輯運算主要包括三種:與或非,之后在這三種基礎(chǔ)上又出現(xiàn)了異或(這里不再介紹)。
在Linux中與或非的運算符號為:
與 : && ? ? 在測試命令中有時也會用-a表示與
或 : || ? ? 在測試命令中有時也會用-o表示或
非 : !
與、或、非運算:
與運算: 1 && 1 = 1 ? ? ?1 && 0 = 0
或運算: 1 || 1 = 1 ? ? ?1 || 0 = 1 ? ? ? ?0 || 1 = 1 ? ? ? ? 0 || 0 = 0
非運算: ?! 1 = 0 ? ? ? ?! 0 = 1
在計算機中由于用1表示真,0表示假,故上面的三種運算也可以看做如下概念:
與運算: 真 && 真 = 真 ? 真 && 假 = 假
或運算: 真 || 真 = 真 ? 真 || 假 = 真 ? ? 假 || 真 = 真 ? ? ?假 || 假 = 假
非運算: ?! 真 = 假 ? ? ? ?! 假 = 真
在測試中常用的邏輯運算中的定律
德摩根定律:
非(P 且 Q)=(非 P)或(非 Q)
非(P 或 Q)=(非 P)且(非 Q)
它在測試中的作用:通常為了化簡邏輯表達式。
比如在一個測試表達式中出現(xiàn)了多個-a或-o使用德摩根定律可以減少其個數(shù)
! a == b -a ! c == d -a ! d == a 等價于!( a == b -o c == d -o d == a )
當(dāng)前面-not或!很多時可以使用這種表示方式,這兩種是等價的
測試表達式:
測試表達式分三種:
1、test EXPRESSION
2、[ EXPRESSION ]
3、` EXPRESSION `
上面三種使用各有其適用范圍,限于所學(xué)有限沒有能力對其進行一一歸納,我覺得剛開始學(xué)不需要求全責(zé)備,先掌握大體知識框架比較好。之后在實際中遇到再慢慢進行總結(jié)。腳本寫的多,遇到的問題多,這三種的使用場景自然就心領(lǐng)神會了。
條件測試:數(shù)值測試、字符串傳測試、文件測試
數(shù)值測試:判斷兩個數(shù)值的大小及是否相等,有如下
-gt:是否大于 ? ? ?大于為真,否則為假
-ge:是否大于等于 ?大于等于為真,否則為假
-eq:是否等于 ? ? ?等于為真,否則為假
-ne:是否不等于 ? ?不等于為真,否則為假
-lt:是否小于 ? ? ?小于為真,否則為假
-le:是否小于等于 ?小于等于為真,否則為假
下面是一個小例子顯示其簡單用法,$?是執(zhí)行狀態(tài)返回值,可以查看上一條命令執(zhí)行結(jié)果的真與假,0表示為真,1-255為假。[root@localhost?test]#?[?1?-eq?2?]
[root@localhost?test]#?echo?$?
1
我們判斷1是否等于2,狀態(tài)返回值為1判斷執(zhí)行結(jié)果為假,所以1不等于2.
………………………………………………………………………………………………………………………
字符串測試:判斷字符串是否符合或等于給定的字符串
字符串的判斷大小是依據(jù)ASCII中字符對應(yīng)的數(shù)字大小進行
==:是否等于 ? ? 等于為真,否則為假
>:是否大于 ? ? ?大于為真,否則為假
!=:是否不等于 ?不等于為真,否則為假
=~:左側(cè)字符串是否能夠被右側(cè)的PATTERN(正則表達式)所匹配 ?若匹配則為真,否則為假
-z “string” : 測試字符串是否為空,空則為真,否則為假
-n “string” :測試字符串是否不為空,不空為真,否則為假
下面也舉一個簡單的例子展示字符串測試用法[root@localhost?test]#?[?a?==?b?]
[root@localhost?test]#?echo?$?
1
[root@localhost?test]#?[?a?
-bash:?b:?沒有那個文件或目錄
[root@localhost?test]#?[?"a"?
-bash:?b:?沒有那個文件或目錄
[root@localhost?test]#?[[?"a"?
[root@localhost?test]#?echo?$?
0
這里我先對ab是否相等進行判斷,之后查看結(jié)果是假,也就是a不是b。之后對其進行大小判斷,然后報錯,先為ab加""結(jié)果報錯,之后又加了[]才未報錯。這里我們可以看到在字符串測試中使用` `方式進行會比較靠譜,但也不一定。用[]還是` `就是在這種測試中摸索出來的。
下面再對字符是否為空舉一個例子[root@localhost?test]#?name1=
[root@localhost?test]#?[?-z?$name1?]
[root@localhost?test]#?echo?$?
0
[root@localhost?test]#?[?-n?$name1?]
[root@localhost?test]#?echo?$?
0
怎么會出現(xiàn)這種情況?字符測試為空竟然不靈!別慌,上面我們曾有經(jīng)驗,字符測試如果單中括號失敗那就試試雙中括號[root@localhost?test]#?[[?-z?$name1?]]
[root@localhost?test]#?echo?$?
0
[root@localhost?test]#?[[?-n?$name1?]]
[root@localhost?test]#?echo?$?
1
結(jié)果終于如愿,上面的兩個例子告訴我們,當(dāng)測試結(jié)果并不是對時,調(diào)整下中括號往往有奇效。
………………………………………………………………………………………………………………………
文件測試:
1、存在性測試
-a FILE (少用)
-eFILE 文件存在性測試,存在為真,否則為假[root@localhost?test]#?[?-e?/etc/fstab?]
[root@localhost?test]#?echo?$?
0
[root@localhost?test]#?[[?-e?/etc/ftab?]]
[root@localhost?test]#?echo?$?
1
2、存在性及類別測試
-b FILE:是否存在且為塊設(shè)備文件,存在為真否則為假
-c FILE:是否存在且為字符設(shè)備文件,存在為真,否則為假
-f FILE:是否存在且為普通文件,存在為真,否則為假
-d FILE:是否存在且為目錄文件,存在為真,否則為假
-h FILE 或 -L FILE :是否存在且為鏈接文件,存在為真,否則為假
-p FILE:是否存在且為命名管道文件,存在為真,否則為假
-S FILE:是否存在且為套接字文件,存在為真,否則為假[root@localhost?test]#?[?-f?/test/if1?]
[root@localhost?test]#?echo?$?
0
[root@localhost?test]#?[?-f?/test/?]
[root@localhost?test]#?echo?$?
1
3、文件權(quán)限測試
-r FILE:是否存在且對當(dāng)前用戶可讀,存在為真,否則為假
-w FILE:是否存在且對當(dāng)前用戶可寫,存在為真,否則為假
-x FILE:是否存在且對當(dāng)前用戶可執(zhí)行,存在為真,否則為假[root@localhost?test]#?echo?$USER
root
[root@localhost?test]#?[?-r?/test/?]
[root@localhost?test]#?echo?$?
0
4、文件特殊權(quán)限測試
-g FILE:是否存在且擁有sgid,存在為真,否則為假
-u FILE:是否存在且擁有suid,存在為真,否則為假
-k FILE:是否存在且擁有sticky,存在為真,否則為假[root@localhost?test]#?[?-g?/test/if1?]
[root@localhost?test]#?echo?$?
1
[root@localhost?test]#?ll?/test/if1
-rwxr-xr-x.?1?root?root?149?8月??15?10:34?/test/if1
5、文件大小測試
-s FILE:是否存在且非空,存在為真,否則為假[root@localhost?test]#?[?-s?/test/file1?]
[root@localhost?test]#?echo?$?
1
[root@localhost?test]#?echo?>?file1
[root@localhost?test]#?[?-s?/test/file1?]
[root@localhost?test]#?echo?$?
0
6、文件時間戳測試
-N FILE:文件自上一次被讀取之后是否被修改過,被修改過為真,否則為假
選取剛剛被修改過得file1測試[root@localhost?test]#?[?-N?/test/file1?]
[root@localhost?test]#?echo?$?
0
7、文件從屬關(guān)系測試
-O FILE:當(dāng)前用戶是否為文件的屬主,是為真,否為假
-GFILE:當(dāng)前用戶是否屬于文件的屬組,是為真,否為假[root@localhost?test]#?[?-O?/test/if1?]
[root@localhost?test]#?echo?$?
0
[root@localhost?test]#?ll?/test/if1
-rwxr-xr-x.?1?root?root?149?8月??15?10:34?/test/if1
8、雙目測試
FILE1 -ef FILE2:FILE1與FILE2是否指向同一個文件系統(tǒng)的相同inode的硬鏈接,是則為真,否為假
FILE1 -nt FILE2 :FILE1的mtime是否新于FILE2,是為真,否為假
FILE1 -ot FILE2 :FILE1的mtime是否舊于FILE2,是為真,否為假[root@localhost?test]#?[?/test/if1?-nt?/test/file1?]
[root@localhost?test]#?echo?$?
1
因為file1剛剛被修改過,所以它比if1文件的mtine要新,因為使用-nt故測試結(jié)果為假
組合測試
第一種方式:
與 ?COMMAND1 && COMMAND2第一條命令為假后不再執(zhí)行第二條命令,為真方執(zhí)行。
或 ?COMMAND1 || COMMAND2第一條命令為真后不再執(zhí)行第二條命令,為假方執(zhí)行。
非 ?! COMMAND對命令結(jié)果的真假取反
第二種方式:
EXPRESSION -a EXPRESSION第一條命令為假后不再執(zhí)行第二條命令,為真方執(zhí)行。
EXPRESSION -o EXPRESSION第一條命令為真后不再執(zhí)行第二條命令,為假方執(zhí)行。
! EXPRESSION對命令結(jié)果的真假取反
示例:比較1是否比2小若其為真則進而比較字符name是否等于Name
第一種表達方式:[root@localhost?test]#?[[?1?-lt?2?]]?&&?[[?name?==?Name?]]
第二種表達方式:[root@localhost?test]#?[[?1?-lt?2?-a?name?==?Name?]]
-bash:?條件表達式中有語法錯誤
-bash:?`-a'?附近有語法錯誤
[root@localhost?test]#?[?1?-lt?2?-a?name?==?Name?]
用[]還是` `有時真的需要一遍遍的測試。
腳本實踐
簡要介紹下腳本相關(guān)內(nèi)容
shell腳本也屬于一種語言,這種語言屬于弱類型,不需要聲明數(shù)據(jù)的存儲格式,bash中均當(dāng)做字符處理,它靠解釋器運行。
寫腳本前需要在所打開文件第一行頂格給出shebang,解釋器路徑對于bash就是#!/bin/bash。
運行腳本
1、賦予執(zhí)行權(quán)限,并直接運行此程序文件常見格式為:./文件名
2、直接運行解釋器,將腳本以命令參數(shù)傳遞給解釋器程序:bash
腳本實例
1、寫一個腳本/root/bin/argsnum.sh,接受一個文件路徑作為參數(shù);如果參數(shù)個數(shù)小于1,則提示用戶“至少應(yīng)該給一個參數(shù)”,并立即退出;如果參數(shù)個數(shù)不小于1,則顯示第一個參數(shù)所指向的文件中的空白行數(shù)[root@localhost?test]#?cat?scrip1
#!/bin/bash
#
[?$#?-lt?1?]?&&?echo?"At?least?provide?one?path"?&&?exit?1
lines_space=`grep?'^$'?$1?|?wc?-l`
[?$#?-eq?1?]?&&?echo?"The?space?lines?of?the?first?file?are?:$lines_space"
[?$#?-gt?1?]?&&?echo?"None?message"?&&?exit?2
[root@localhost?test]#?chmod?+x?scrip1
[root@localhost?test]#?./scrip1?/etc/fstab
The?space?lines?of?the?first?file?are?:1
[root@localhost?test]#?./scrip1?/etc/fstab?/etc
None?message
[root@localhost?test]#?./scrip1
At?least?provide?one?path
腳本中用到了特殊變量$#,位置變量$1,數(shù)值測試,組合測試,變量引用
2、寫一個腳本/root/bin/hostping.sh,接受一個主機的IPv4地址做為參數(shù),先判斷是否合格IP,否,提示IP格式不合法并退出,是,測試是否可連通。如果能ping通,則提示用戶“該IP地址可訪問”;如果不可ping通,則提示用戶“該IP地址不可訪問”[root@localhost?test]#?cat?scrip2
#!/bin/bash
#
[?$#?-lt?1?]?&&?echo?"please?give?one?IP?address"?&&?exit?1
[?$#?-gt?1?]?&&?echo?"this?script?just?match?one?IP?address"?&&?exit?2
[?$#?-eq?1?]?&&?[[?$1?=~?(([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\.){3}([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])?]]?&&?ping?-c?1?$1?|?sed?-n?'2p'|grep?-o?'^64'?>>?/dev/null?&&?echo?"該IP地址可訪問"?||?echo?"該IP地址不可訪問"
[root@localhost?test]#?chmod?+x?scrip2
[root@localhost?test]#?./scrip2
please?give?one?IP?address
[root@localhost?test]#?./scrip2?192.168.1.1
該IP地址不可訪問
[root@localhost?test]#?./scrip2?192.168.85.3
該IP地址可訪問
[root@localhost?test]#?./scrip2?192.168.85.3?192.168.168.1
this?script?just?match?one?IP?address
上面思路,先判斷參數(shù)個數(shù),也就是是否在腳本后加IP。然后判斷IP是否符合規(guī)范,之后進行若IP可ping通給出相應(yīng)提示,這個腳本的大致思路就是這樣。
關(guān)于腳本的個人感受
寫腳本前先要理清楚思路,這個問題要怎么解決,對哪些內(nèi)容要進行測試,都需要用到哪些測試方法,需要設(shè)置哪些變量,用到哪些組合測試...
上述確定后就開始寫,寫完再進行調(diào)試。很多時候就算自己想的都沒錯,可是腳本寫完依舊不能成功執(zhí)行或達成想要的結(jié)果,因為初學(xué)總會出現(xiàn)各種意料不到的情況比如[]與` `的錯誤使用,比如命令引用忘記加``等等細節(jié)。
總結(jié)
以上是生活随笔為你收集整理的linux的逻辑运算参数,Linux基础之bash脚本编程初级-逻辑运算与测试的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 天亮就出发是哪首歌啊?
- 下一篇: linux系统安装deamonsync,