文件測試即使用指定條件來判斷文件是否存在或權限是否滿足等情況的運算符


在本書前面章節中講到,系統在執行mkdir命令時會判斷用戶輸入的信息,即判斷用戶指定的文件夾名稱是否已經存在,如果存在則提示報錯;反之則自動創建。Shell腳本中的條件測試語法可以判斷表達式是否成立,若條件成立則返回數字0,否則便返回其他隨機數值。條件測試語法的執行格式如圖4-16所示。切記,條件表達式兩邊均應有一個空格。

第4章 Vim編輯器與Shell命令腳本。第4章 Vim編輯器與Shell命令腳本。

圖4-16  條件測試語句的執行格式


按照測試對象來划分,條件測試語句可以分為4種:

文件測試語句;

邏輯測試語句;

整數值比較語句;

字符串比較語句。

文件測試即使用指定條件來判斷文件是否存在或權限是否滿足等情況的運算符,具體的參數如表4-3所示。

表4-3                                                    文件測試所用的參數

操作符 作用
-d 測試文件是否為目錄類型
-e 測試文件是否存在
-f 判斷是否為一般文件
-r 測試當前用戶是否有權限讀取
-w 測試當前用戶是否有權限寫入
-x 測試當前用戶是否有權限執行

 

下面使用文件測試語句來判斷/etc/fstab是否為一個目錄類型的文件,然后通過Shell解釋器的內設$?變量顯示上一條命令執行后的返回值。如果返回值為0,則目錄存在;如果返回值為非零的值,則意味着目錄不存在:

[root@linuxprobe ~]# [ -d /etc/fstab ]
[root@linuxprobe ~]# echo $?
1

再使用文件測試語句來判斷/etc/fstab是否為一般文件,如果返回值為0,則代表文件存在,且為一般文件:

[root@linuxprobe ~]# [ -f /etc/fstab ]
[root@linuxprobe ~]# echo $?
0

邏輯語句用於對測試結果進行邏輯分析,根據測試結果可實現不同的效果。例如在Shell終端中邏輯“與”的運算符號是&&,它表示當前面的命令執行成功后才會執行它后面的命令,因此可以用來判斷/dev/cdrom文件是否存在,若存在則輸出Exist字樣。

[root@linuxprobe ~]# [ -e /dev/cdrom ] && echo "Exist"
Exist

除了邏輯“與”外,還有邏輯“或”,它在Linux系統中的運算符號為||,表示當前面的命令執行失敗后才會執行它后面的命令,因此可以用來結合系統環境變量USER來判斷當前登錄的用戶是否為非管理員身份:

[root@linuxprobe ~]# echo $USER
root
[root@linuxprobe ~]# [ $USER = root ] || echo "user"
[root@linuxprobe ~]# su - linuxprobe 
[linuxprobe@linuxprobe ~]$ [ $USER = root ] || echo "user"
user

第三種邏輯語句是“非”,在Linux系統中的運算符號是一個嘆號(!),它表示把條件測試中的判斷結果取相反值。也就是說,如果原本測試的結果是正確的,則將其變成錯誤的;原本測試錯誤的結果則將其變成正確的。

我們現在切換回到root管理員身份,再判斷當前用戶是否為一個非管理員的用戶。由於判斷結果因為兩次否定而變成正確,因此會正常地輸出預設信息:

[linuxprobe@linuxprobe ~]$ exit
logout
[root@linuxprobe root]# [ $USER != root ] || echo "administrator"
administrator

就技術圖書的寫作來講,一般有兩種套路:讓讀者真正搞懂技術了;讓讀者覺得自己搞懂技術了。因此市面上很多淺顯的圖書會讓讀者在學完之后感覺進步特別快,這基本上是作者有意為之,目的就是讓您覺得“圖書很有料,自己收獲很大”,但是在步入工作崗位后就露出短板吃大虧。所以劉遄老師決定繼續提高難度,為讀者增加一個綜合的示例,一方面作為前述知識的總結,另一方面幫助讀者夯實基礎,能夠在今后工作中更靈活地使用邏輯符號。

當前我們正在登錄的即為管理員用戶—root。下面這個示例的執行順序是,先判斷當前登錄用戶的USER變量名稱是否等於root,然后用邏輯運算符“非”進行取反操作,效果就變成了判斷當前登錄的用戶是否為非管理員用戶了。最后若條件成立則會根據邏輯“與”運算符輸出user字樣;或條件不滿足則會通過邏輯“或”運算符輸出root字樣,而如果前面的&&不成立才會執行后面的||符號。

[root@linuxprobe ~]# [ $USER != root ] && echo "user" || echo "root"
root

整數比較運算符僅是對數字的操作,不能將數字與字符串、文件等內容一起操作,而且不能想當然地使用日常生活中的等號、大於號、小於號等來判斷。因為等號與賦值命令符沖突,大於號和小於號分別與輸出重定向命令符和輸入重定向命令符沖突。因此一定要使用規范的整數比較運算符來進行操作。可用的整數比較運算符如表4-4所示。

表4-4                                                  可用的整數比較運算符

操作符 作用
-eq 是否等於
-ne 是否不等於
-gt 是否大於
-lt 是否小於
-le 是否等於或小於
-ge 是否大於或等於

 

接下來小試牛刀。我們先測試一下10是否大於10以及10是否等於10(通過輸出的返回值內容來判斷):

[root@linuxprobe ~]# [ 10 -gt 10 ]
[root@linuxprobe ~]# echo $?
1
[root@linuxprobe ~]# [ 10 -eq 10 ]
[root@linuxprobe ~]# echo $?
0

在2.4節曾經講過free命令,它可以用來獲取當前系統正在使用及可用的內存量信息。接下來先使用free -m命令查看內存使用量情況(單位為MB),然后通過grep Mem:命令過濾出剩余內存量的行,再用awk '{print $4}'命令只保留第四列,最后用FreeMem=`語句`的方式把語句內執行的結果賦值給變量。

這個演示確實有些難度,但看懂后會覺得很有意思,沒准在運維工作中也會用得上。

[root@linuxprobe ~]# free -m
            total     used     free     shared     buffers     cached
Mem:        1826      1244     582      9          1           413
-/+ buffers/cache:    830 996
Swap:       2047      0        2047
[root@linuxprobe ~]# free -m | grep Mem:
Mem:        1826      1244     582      9 
[root@linuxprobe ~]# free -m | grep Mem: | awk '{print $4}'
582
[root@linuxprobe ~]# FreeMem=`free -m | grep Mem: | awk '{print $4}'`
[root@linuxprobe ~]# echo $FreeMem 
582

上面用於獲取內存可用量的命令以及步驟可能有些“超綱”了,如果不能理解領會也不用擔心,接下來才是重點。我們使用整數運算符來判斷內存可用量的值是否小於1024,若小於則會提示“Insufficient Memory”(內存不足)的字樣:

[root@linuxprobe ~]# [ $FreeMem -lt 1024 ] && echo "Insufficient Memory"
Insufficient Memory

字符串比較語句用於判斷測試字符串是否為空值,或兩個字符串是否相同。它經常用來判斷某個變量是否未被定義(即內容為空值),理解起來也比較簡單。字符串比較中常見的運算符如表4-5所示。

表4-5                                                常見的字符串比較運算符

操作符 作用
= 比較字符串內容是否相同
!= 比較字符串內容是否不同
-z 判斷字符串內容是否為空

 

接下來通過判斷String變量是否為空值,進而判斷是否定義了這個變量:

[root@linuxprobe ~]# [ -z $String ]
[root@linuxprobe ~]# echo $?
0

再嘗試引入邏輯運算符來試一下。當用於保存當前語系的環境變量值LANG不是英語(en.US)時,則會滿足邏輯測試條件並輸出“Not en.US”(非英語)的字樣:

[root@linuxprobe ~]# echo $LANG
en_US.UTF-8
[root@linuxprobe ~]# [ $LANG != "en.US" ] && echo "Not en.US"
Not en.US

出現問題?大膽提問!

因讀者們硬件不同或操作錯誤都可能導致實驗配置出錯,請耐心再仔細看看操作步驟吧,不要氣餒~

Linux技術交流請加A群:560843(滿),B群:340829(推薦),C群:463590(推薦),點此查看全國群

*本群特色:通過口令驗證確保每一個群員都是《Linux就該這么學》的讀者,答疑更有針對性,不定期免費領取定制禮品。

4.3 流程控制語句

盡管此時可以通過使用Linux命令、管道符、重定向以及條件測試語句來編寫最基本的Shell腳本,但是這種腳本並不適用於生產環境。原因是它不能根據真實的工作需求來調整具體的執行命令,也不能根據某些條件實現自動循環執行。例如,我們需要批量創建1000位用戶,首先要判斷這些用戶是否已經存在;若不存在,則通過循環語句讓腳本自動且依次創建他們。

接下來我們通過if、for、while、case這4種流程控制語句來學習編寫難度更大、功能更強的Shell腳本。為了保證下文的實用性和趣味性,做到寓教於樂,我會盡可能多地講解各種不同功能的Shell腳本示例,而不是逮住一個腳本不放,在它原有內容的基礎上修修補補。盡管這種修補式的示例教學也可以讓讀者明白理論知識,但是卻無法開放思路,不利於日后的工作。

4.3.1 if條件測試語句

if條件測試語句可以讓腳本根據實際情況自動執行相應的命令。從技術角度來講,if語句分為單分支結構、雙分支結構、多分支結構;其復雜度隨着靈活度一起逐級上升。

if條件語句的單分支結構由if、then、fi關鍵詞組成,而且只在條件成立后才執行預設的命令,相當於口語的“如果……那么……”。單分支的if語句屬於最簡單的一種條件判斷結構,語法格式如圖4-17所示。
第4章 Vim編輯器與Shell命令腳本。第4章 Vim編輯器與Shell命令腳本。

圖4-17  單分支的if語句

下面使用單分支的if條件語句來判斷/media/cdrom文件是否存在,若存在就結束條件判斷和整個Shell腳本,反之則去創建這個目錄:

[root@linuxprobe ~]# vim mkcdrom.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi

由於第5章才講解用戶身份與權限,因此這里繼續用“bash 腳本名稱”的方式來執行腳本。在正常情況下,順利執行完腳本文件后沒有任何輸出信息,但是可以使用ls命令驗證/media/cdrom目錄是否已經成功創建:

[root@linuxprobe ~]# bash mkcdrom.sh
[root@linuxprobe ~]# ls -d /media/cdrom
/media/cdrom


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM