什么是Shell
在Linux系統(tǒng)中,Shell是用戶與系統(tǒng)內(nèi)核之間進(jìn)行交互的接口。
Shell這個(gè)單詞的意思是“外殼”,它形象地表達(dá)出了Shell的作用。在UNIX以及Linux中,Shell就是套在內(nèi)核外面的一層外殼。正因?yàn)橛蠸hell的存在,才向普通的用戶隱藏了許多關(guān)于系統(tǒng)內(nèi)核的細(xì)節(jié)。
Shell又稱命令解釋器,它能識(shí)別用戶輸入的各種命令,并傳遞給操作系統(tǒng)。它的作用類似于Windows操作系統(tǒng)中的命令行,但是,Shell的功能遠(yuǎn)比命令行強(qiáng)大得多。在UNIX或者Linux中,Shell既是用戶交互的界面,也是控制系統(tǒng)的腳本語(yǔ)言。
Shell的分類關(guān)于Shell的分類,在介紹Shell的歷史的時(shí)候已經(jīng)簡(jiǎn)單地介紹過一些了,下面對(duì)各種Shell程序做一個(gè)簡(jiǎn)單的概括。常見的幾種Shell程序如下所述。
BourneShell:標(biāo)識(shí)為sh,該Shell由SteveBourne在貝爾實(shí)驗(yàn)室時(shí)編寫。在許多UNIX系統(tǒng)中,該Shell是root用戶的默認(rèn)的Shell。BourneAgainShell:標(biāo)識(shí)為bash,該Shell由BrianFox在1987年編寫,是絕大多數(shù)Linux發(fā)行版的默認(rèn)的Shell。KornShell:標(biāo)識(shí)為ksh,該Shell由貝爾實(shí)驗(yàn)室的DavidKorn在二十世紀(jì)八十年代早期編寫。它完全向上兼容BourneShell并包含了CShell的很多特性。C Shell:標(biāo)識(shí)為csh,該Shell由BillJoy在BSD系統(tǒng)上開發(fā)。由于其語(yǔ)法類似于C語(yǔ)言,因此稱為CShell。對(duì)于這些Shell程序,其語(yǔ)法或多或少都有所區(qū)別。目前大部分人仍然建議使用標(biāo)準(zhǔn)的BourneAgainShell。
Shell不僅僅是充當(dāng)用戶與UNIX或者Linux交互界面的角色,還可以作為一種程序設(shè)計(jì)語(yǔ)言來(lái)使用。通過Shell編程,可以實(shí)現(xiàn)許多非常實(shí)用的功能,提高系統(tǒng)管理的自動(dòng)化水平。
在linux上搭建Shell編程環(huán)境由于Linux本身都會(huì)默認(rèn)安裝Shell腳本的運(yùn)行環(huán)境,所以通常情況下,并不需要用戶額外安裝什么軟件。
在同一臺(tái)Linux上面會(huì)同時(shí)安裝多個(gè)Shell,并且,這些Shell的語(yǔ)法會(huì)有所不同,所以,用戶在編寫和執(zhí)行Shell腳本的時(shí)候一定要弄清楚當(dāng)前使用的是哪種Shell。用戶可以使用系統(tǒng)變量$SHELL來(lái)獲取當(dāng)前系統(tǒng)默認(rèn)的Shell。
echo $SHELL
從上面的輸出結(jié)果可以得知,當(dāng)前系統(tǒng)默認(rèn)的Shell為bash。
我們都是指定使用的Shell為/bin/sh。實(shí)際上,在Linux中,這是一個(gè)指向/bin/bash的符號(hào)鏈接,如下:
這意味著,盡管我們?cè)诔绦蛑兄付ǖ慕忉屍鳛?bin/sh,但是實(shí)際上解釋Shell腳本的是/bin/bash。
Shell作為一個(gè)軟件包,當(dāng)然也有版本,用戶可以使用如下命令來(lái)查看bash的版本:
echo $BASH_VERSIONShell 如何執(zhí)行
Shell腳本程序有以下兩種執(zhí)行方式:
(1)用戶可以依次輸入一系列的命令,交互式地執(zhí)行它們;
(2)用戶也可以把所有的這些命令按照順序保存在一個(gè)文件中,然后將該文件作為一個(gè)程序來(lái)執(zhí)行。
交互式程序在命令行上直接輸入命令來(lái)交互式地執(zhí)行Shell腳本是一種非常簡(jiǎn)單的方式。尤其是在測(cè)試Shell程序的時(shí)候,通過使用交互式方式,可以非常方便地得到程序執(zhí)行的結(jié)果。
例:在當(dāng)前目錄中查找文件名包含“xml”這3個(gè)字符的文件。如果找到的話,則在當(dāng)前屏幕上打印出來(lái)。我們可以在Shell提示符后面依次輸入下面的代碼:
[root@linux~]# for filename in `ls .`> do> if echo "$filename" | grep "xml"> then > echo "$filename"> fi> donepackage.xmlpackage.xmlwbxml1.0.3wbxml1.0.3wbxml1.0.3.tgzwbxml1.0.3.tgz
命令行直接執(zhí)行功能相同:
for filename in `ls .`; do if echo “$filename” | grep “xml”; then echo “$filename”; fi; done
創(chuàng)建腳本對(duì)于一組需要經(jīng)常重復(fù)執(zhí)行的Shell語(yǔ)句來(lái)說(shuō),將它們保存在一個(gè)文件中來(lái)執(zhí)行是一種非常明智的做法。我們通常稱這種包含多個(gè)Shell語(yǔ)句的文件為Shell腳本,或者Shell腳本文件。腳本文件都是普通的文本文件,可以使用任何的文本編輯器查看或者修改Shell腳本文件。
#! /bin/sh# for 循環(huán)開始for filename in `ls .`do #如果文件名包含xml if echo "$filename" | grep "xml"; then #輸出文件名 echo "$filename" fidone
從上面的代碼可以得知,Shell程序中的注釋以“#”符號(hào)開始,一直持續(xù)到該行的結(jié)束。請(qǐng)注意第一行#!/bin/sh,它是一種特殊形式的注釋,其中,“#!”字符告訴系統(tǒng)同一行中緊跟在它后面的那個(gè)參數(shù)是用來(lái)執(zhí)行本文件的程序。在這個(gè)例子中,/bin/sh是默認(rèn)的Shell程序。當(dāng)將腳本編輯完成之后,這個(gè)腳本還不能馬上執(zhí)行,把腳本設(shè)置為可執(zhí)行。
Shell腳本的參數(shù)從命令行傳遞給Shell腳本的參數(shù)又稱為位置參數(shù),這主要是因?yàn)镾hell腳本會(huì)根據(jù)參數(shù)的位置來(lái)接收它們的值。在Shell腳本內(nèi)部,用戶可以通過一系列的系統(tǒng)變量來(lái)獲取參數(shù)。這些變量的名稱都是固定的,并且非常簡(jiǎn)單,只用1個(gè)字符表示,例如$0表示當(dāng)前執(zhí)行的腳本名稱,$1表示傳遞給腳本的第1個(gè)參數(shù)等。
注:
由單引號(hào)或者雙引號(hào)引起來(lái)的字符串作為一個(gè)參數(shù)進(jìn)行傳遞,傳遞時(shí)會(huì)去掉引號(hào)。
對(duì)于包含空白字符或者其他的特殊字符的參數(shù),需要使用單引號(hào)或者雙引號(hào)進(jìn)行傳遞。
變量$@可以以“參數(shù)1”“參數(shù)2”“參數(shù)3”……的形式返回所有的參數(shù)的值,因此,$@與“$1”“$2”“$3”……是等價(jià)的。如果用戶傳遞的參數(shù)中包含空格或者其他的特殊字符,需要使用$@來(lái)獲取所有的參數(shù)的值,不能使用$*。
變量$*以“參數(shù)1參數(shù)2參數(shù)3……”的形式將所有的參數(shù)作為一個(gè)字符串返回。通常情況下,參數(shù)值之間通過空格、制表符或者換行符來(lái)隔開,在默認(rèn)情況下使用空格。
變量$#返回傳遞給腳本的參數(shù)的數(shù)量,不包括$0,即排除腳本的名稱。
另外,如果用戶傳遞的參數(shù)多于9個(gè),則不能使用$10來(lái)引用第10個(gè)參數(shù)。為了能夠獲取第10個(gè)參數(shù)的值,用戶必須處理或保存第1個(gè)參數(shù),即$1,然后使用shift命令刪除參數(shù)1并將所有剩余的參數(shù)下移1位,此時(shí)$10就變成了$9,依此類推。$#的值將被更新以反映參數(shù)的剩余數(shù)量。
參數(shù)擴(kuò)展用戶需要編寫一個(gè)腳本程序,并且這個(gè)腳本程序需要一個(gè)擁有許多值得參數(shù),在程序中,用戶希望根據(jù)這個(gè)參數(shù)的值來(lái)執(zhí)行不同的操作。在這種情況下,單純地依靠$1以及$2等變量已經(jīng)不能滿足需求了。此時(shí),用戶可以考慮使用參數(shù)擴(kuò)展。
為了獲取到這些參數(shù)的值,用戶需要在Shell程序中使用getopts命令。
Shell腳本的基本元素第2行,指定命令解讀器:“#!/bin/bash”。
第4行,注釋:說(shuō)明某些代碼的功能。
第5行,可執(zhí)行語(yǔ)句:實(shí)現(xiàn)程序的功能。
指定命令解讀器通常會(huì)同時(shí)安裝多個(gè)Shell程序,例如sh、bash或者csh等。而這些不同的Shell程序的語(yǔ)法會(huì)有些區(qū)別,那么到底使用哪個(gè)Shell來(lái)執(zhí)行代碼呢?
當(dāng)用戶在命令行中執(zhí)行該程序時(shí),當(dāng)前的Shell會(huì)載入該程序的代碼,并且讀取其中的第2行,如果發(fā)現(xiàn)有“#!”標(biāo)識(shí),則表示當(dāng)前的程序指定了解釋并執(zhí)行它的Shell。然后會(huì)嘗試讀取“#!”標(biāo)識(shí)后面的內(nèi)容,搜尋解釋器的絕對(duì)路徑。如果發(fā)現(xiàn)了指定的解釋器,則會(huì)創(chuàng)建一個(gè)關(guān)于該解釋器的進(jìn)程,解釋并執(zhí)行當(dāng)前腳本的語(yǔ)句。
Shell腳本的這個(gè)規(guī)定使得用戶可以非常靈活地調(diào)用任何解釋器,而不僅僅限于Shell程序。下面介紹如何在腳本文件中指定其他解釋器程序。
在PHP腳本文件中指定PHP語(yǔ)言的解釋器,然后執(zhí)行文件中的PHP代碼,代碼如下:
Shell腳本中的注釋和風(fēng)格通過在代碼中增加注釋可以提高程序的可讀性。傳統(tǒng)的Shell只支持單行注釋,其表示方法是一個(gè)井號(hào)“#”,從該符號(hào)開始一直到行尾都屬于注釋的內(nèi)容,如果需要多行注釋內(nèi)容的話,則在每行注釋的開頭都要加上“#”。
但是這并不意味著用戶只能使用單行注釋。實(shí)際上,用戶還可以通過其他一些變通的方法來(lái)實(shí)現(xiàn)多行注釋,其中,最簡(jiǎn)單的方法就是使用冒號(hào)“:”配合heredocument,其語(yǔ)法如下:
:<<BLOCK....注釋內(nèi)容BLOCK如何執(zhí)行Shell程序
可以通過3種方式來(lái)實(shí)現(xiàn)。這3種方式分別為:
授予用戶執(zhí)行該腳本文件的權(quán)限,使得該程序能夠直接執(zhí)行。通過調(diào)用Shell腳本解釋器來(lái)執(zhí)行。通過source命令來(lái)執(zhí)行。關(guān)于第一種方法,前面已經(jīng)詳細(xì)介紹過了,不再重復(fù)說(shuō)明。第二種方式就是將腳本文件作為參數(shù)傳遞給解釋器,在通過這種方式執(zhí)行腳本的時(shí)候,不需要用戶擁有執(zhí)行該腳本文件的權(quán)限,只要擁有讀取該文件的權(quán)限即可。
source命令是一個(gè)Shell內(nèi)部命令,其功能是讀取指定的Shell程序文件,并且依次執(zhí)行其中所有的語(yǔ)句。
Shell程序的退出狀態(tài)在UNIX或者Linux中,每個(gè)命令都會(huì)返回一個(gè)退出狀態(tài)碼。退出狀態(tài)碼是一個(gè)整數(shù),其有效范圍為0~255。通常情況下,成功的命令返回0,而不成功的命令返回非0值。非0值通常都被解釋成一個(gè)錯(cuò)誤碼。
同樣,Shell腳本中的函數(shù)和腳本本身也會(huì)返回退出狀態(tài)碼。在腳本或者是腳本函數(shù)中執(zhí)行的最后的命令會(huì)決定退出狀態(tài)碼。另外,用戶也可以在腳本中使用exit語(yǔ)句將指定的退出狀態(tài)碼傳遞給Shell。
在前面的所有的例子中,我們都沒有通過exit語(yǔ)句退出程序。在這種情況下,整個(gè)程序的退出狀態(tài)碼由最后執(zhí)行的那一條語(yǔ)句來(lái)決定,另外,在Shell中,系統(tǒng)變量$?保存了最后一條命令的退出狀態(tài)。
程序的退出狀態(tài)非常重要,它反映了腳本的執(zhí)行是否成功。用戶可以根據(jù)腳本的執(zhí)行狀態(tài)來(lái)決定下一步的操作。
在上面的代碼中,第4行是一個(gè)正常的echo語(yǔ)句,因此第6行的輸出結(jié)果應(yīng)該是0。第8行是一個(gè)無(wú)效的命令,因此第10行會(huì)輸出一個(gè)非0值,具體是什么值要看當(dāng)前Shell的設(shè)置。第11行是一個(gè)正常的echo語(yǔ)句,同樣該語(yǔ)句的退出狀態(tài)也是0。第13行通過exit語(yǔ)句將退出狀態(tài)碼120返回給當(dāng)前的Shell。
變量和引用變量的命令在Shell中,變量名可以由字母、數(shù)字或者下劃線組成,并且只能以字母或者下劃線開頭,大小寫是敏感的。
變量的類型根據(jù)變量類型確定的時(shí)間,可以將程序設(shè)計(jì)語(yǔ)言分為兩類,分別是靜態(tài)類型語(yǔ)言和動(dòng)態(tài)類型語(yǔ)言。其中,靜態(tài)類型語(yǔ)言是在程序的編譯期間就確定變量類型的語(yǔ)言,例如Java、C++和PASCAL,在這些語(yǔ)言中使用變量時(shí),必須首先聲明其類型。動(dòng)態(tài)設(shè)計(jì)語(yǔ)言是在程序執(zhí)行過程中才確定變量的數(shù)據(jù)類型的語(yǔ)言。常見的動(dòng)態(tài)語(yǔ)言有VBScript、PHP及Python等。在這些語(yǔ)言中,變量的數(shù)據(jù)類型根據(jù)第一次賦給該變量的值的數(shù)據(jù)類型來(lái)確定。
同樣,根據(jù)是否強(qiáng)制要求類型定義,可以將程序設(shè)計(jì)語(yǔ)言分為強(qiáng)類型語(yǔ)言和弱類型語(yǔ)言。強(qiáng)類型語(yǔ)言要求用戶在定義變量時(shí)必須明確指定其數(shù)據(jù)類型,例如Java和C++。在強(qiáng)類型語(yǔ)言中,數(shù)據(jù)類型之間的轉(zhuǎn)換非常重要。與之相反,弱類型語(yǔ)言則不要求用戶明確指定變量的數(shù)據(jù)類型,例如VBScript。用戶可以將任意類型的數(shù)值賦給該變量。并且,變量的數(shù)據(jù)類型之間的轉(zhuǎn)換也無(wú)需明確進(jìn)行。
Shell是一種動(dòng)態(tài)類型語(yǔ)言和弱類型語(yǔ)言,即在Shell中,變量的數(shù)據(jù)類型無(wú)需顯示地聲明,變量的數(shù)據(jù)類型會(huì)根據(jù)不同的操作有所變化。準(zhǔn)確地講,Shell中的變量是不分?jǐn)?shù)據(jù)類型的,統(tǒng)一地按照字符串存儲(chǔ)。
在Shell中,通常情況下用戶可以直接使用變量,無(wú)需先進(jìn)行定義,當(dāng)用戶第一次使用某個(gè)變量名時(shí),實(shí)際上就同時(shí)定義了這個(gè)變量,在變量的作用域內(nèi),用戶都可以使用該變量。
盡管通過以上方式可以非常方便地定義變量,但是,對(duì)于變量的某些屬性卻不容易控制,例如,變量的類型和讀寫屬性等。為了更好地控制變量的相關(guān)屬性,bash提供了一個(gè)名稱為declare的命令來(lái)聲明變量,該命令的基本語(yǔ)法如下:
以上程序的執(zhí)行結(jié)果如下:
下面對(duì)比執(zhí)行結(jié)果分析一下代碼。
第5行使用通常的方法定義了一個(gè)變量x,并且將一個(gè)算術(shù)式作為初始值賦給該變量。第6行輸出變量x的值。前面已經(jīng)講過,Shell中將所有的數(shù)據(jù)都看做是字符串來(lái)存儲(chǔ)的,所以在程序執(zhí)行的時(shí)候,Shell并不將6/3當(dāng)成一個(gè)將被求值的算術(shù)式,而是作為一個(gè)普通的字符串,所以第6行直接輸出了這個(gè)算術(shù)式本身,得到了結(jié)果的第2行。
代碼的第8行使用declare語(yǔ)句聲明了變量x為整數(shù),但是程序并沒對(duì)變量x重新賦值,所以第9行的echo語(yǔ)句的執(zhí)行結(jié)果仍然得到算術(shù)式本身,即結(jié)果的第3行。
代碼的第11行對(duì)變量x重新賦值,將前面的算術(shù)表達(dá)式賦給它。因?yàn)楫?dāng)變量被聲明為整數(shù)之后,可以直接參與算術(shù)運(yùn)算,所以第12行的echo語(yǔ)句中輸出了算術(shù)式的值,即結(jié)果的第4行。
第14行嘗試將一個(gè)字符串值賦給整數(shù)變量x,并且在第15行使用echo語(yǔ)句輸出x的值。在Shell中,如果變量被聲明成整數(shù),把一個(gè)結(jié)果不是整數(shù)的表達(dá)式賦值給它時(shí),就會(huì)變成0。因此,結(jié)果第5行中的0是代碼第15行的echo語(yǔ)句的輸出。
第17行將一個(gè)浮點(diǎn)數(shù)賦給變量x,因?yàn)閎ash并不內(nèi)置對(duì)浮點(diǎn)數(shù)的支持,所以得到了執(zhí)行結(jié)果中的第6行的錯(cuò)誤消息,此時(shí),變量x的值變?yōu)?,即結(jié)果的第7行中的0。
第20行取消變量x的整數(shù)類型屬性,第22行重新將算術(shù)式賦給變量x,并且在第23行使用echo語(yǔ)句輸出變量x的值。由于此時(shí)變量x已經(jīng)不是整數(shù)變量,所以不能直接參數(shù)算術(shù)運(yùn)算。因此,變量x的值仍然得到了算術(shù)式本身,即結(jié)果的第8行。
在Shell中,為了得到算術(shù)式的值,可以有兩種方法,其中一種就是使用方括號(hào),即第25行中的方式。結(jié)果的第9行正是此時(shí)變量x的值。另外一種是使用圓括號(hào),即第28行中的方式。從執(zhí)行結(jié)果可以得知,這兩種方式都可以得到用戶所期望的結(jié)果。
第31行使用r選項(xiàng)聲明了一個(gè)只讀變量,第43行嘗試為該變量重新賦值,從而得到了結(jié)果中第12行的錯(cuò)誤消息。此時(shí)變量x的值仍然是2,所以才有結(jié)果中的第13行。
變量和引號(hào)Shell變量中的符號(hào)“$”表示取變量的值。只有在取值的時(shí)候才使用,定義和賦值時(shí)無(wú)需使用符號(hào)“$”。另外,實(shí)際上Shell中變量的原型為${var},而常用的書寫形式$var只是一個(gè)簡(jiǎn)寫。在某些情況下,簡(jiǎn)寫形式會(huì)導(dǎo)致程序執(zhí)行錯(cuò)誤。
Shell語(yǔ)言中一共有3種引號(hào),分別為單引號(hào)(”)、雙引號(hào)(””)和反引號(hào)(“)。這3種引號(hào)的作用是不同的,其中單引號(hào)括起來(lái)的字符都作為普通字符出現(xiàn);由雙引號(hào)括起來(lái)的字符,除“$”、“”、“’”和“””這幾個(gè)字符仍是特殊字符并保留其特殊功能外,其余字符仍作為普通字符對(duì)待;由反引號(hào)括起來(lái)的字串被Shell解釋為命令,在執(zhí)行時(shí),Shell首先執(zhí)行該命令,并以它的標(biāo)準(zhǔn)輸出結(jié)果取代整個(gè)反引號(hào)(包括兩個(gè)反引號(hào))部分。
變量的作用域1、全局變量
通常認(rèn)為,全局變量是使用范圍較大的變量,它不僅限于某個(gè)局部使用。在Shell語(yǔ)言中,全局變量可以在腳本中定義,也可以在某個(gè)函數(shù)中定義。在腳本中定義的變量都是全局變量,其作用域?yàn)閺谋欢x的地方開始,一直到Shell腳本結(jié)束或者被顯式地刪除。
除了在腳本中定義全局變量之外,在函數(shù)內(nèi)部定義的變量默認(rèn)情況下也是全局變量,其作用域?yàn)閺暮瘮?shù)被調(diào)用時(shí)執(zhí)行變量定義的地方開始,一直到Shell腳本結(jié)束或者被顯式地刪除為止。
2、局部變量
與全局變量相比,局部變量的使用范圍較小,通常僅限于某個(gè)程序段訪問,例如函數(shù)內(nèi)部。在Shell語(yǔ)言中,可以在函數(shù)內(nèi)部通過local關(guān)鍵字定義局部變量,另外,函數(shù)的參數(shù)也是局部變量。
系統(tǒng)變量環(huán)境變量按照慣例,Shell中的環(huán)境變量全部使用大寫字母表示。
演示通過環(huán)境變量來(lái)獲取與當(dāng)前Shell有關(guān)的一些環(huán)境變量的值,代碼如下:
變量賦值一個(gè)沒有初始化的Shell變量被認(rèn)為是一個(gè)空字符串。用戶可以通過變量的賦值操作來(lái)完成變量的聲明并賦予一個(gè)特定的值。并且可以通過賦值語(yǔ)句為一個(gè)變量多次賦值,以改變其值。
一般情況下,Shell中將所有普通變量的值都看做字符串。如果value中包含空格、制表符和換行符,則必 須用單引號(hào)或者雙引號(hào)將其引起來(lái)。雙引號(hào)內(nèi)允許變量替換,而單引號(hào)則不可以。中間的等于號(hào)“=” 稱為賦值符號(hào),賦值符號(hào)的左右兩邊不能直接跟空格,否則 Shell會(huì)將其視為命令。
引用變量的值在 Shell 中,用戶可以通過在變量名前面加上“$”來(lái)獲取該變量的值。例如:$str。
為了能夠使 Shell正確地界定變量名,避免混淆,用戶在引用變量時(shí)可以使用大括號(hào)將變量名括起來(lái)。例如:${str}abc。
清除變量使用unt語(yǔ)句:unt varicable_name
引用符號(hào)命令替換所謂命令替換, 是指在 Shell 程序中,將某個(gè) Shell 命令的執(zhí)行結(jié)果賦給某個(gè)變量。在bash中,有兩種語(yǔ)法可以進(jìn)行命令替換, 分別使用反引號(hào)和圓括號(hào), 如下:
`shell_command` 或者 $(shell_command)
條件測(cè)試在Shell程序中,用戶可以使用測(cè)試語(yǔ)句來(lái)測(cè)試指定的條件表達(dá)式的條件的真或者假。當(dāng)指定的條件為真時(shí),整個(gè)條件測(cè)試的返回值為0;反之,如果指定的條件為假,則條件測(cè)試語(yǔ)句的返回值為非0值。
注意:在Shell程序中,條件測(cè)試中的指定條件為真時(shí),條件測(cè)試的返回值為0。這主要是為了保持與Shell程序的退出狀態(tài)一致。當(dāng)某個(gè)Shell程序成功執(zhí)行后,該進(jìn)程會(huì)返回一個(gè)0值;而如果該程序執(zhí)行錯(cuò)誤,則會(huì)返回一個(gè)非0值。
條件測(cè)試的語(yǔ)法有兩種,分別是test命令和[命令,下面對(duì)這兩種語(yǔ)法進(jìn)行介紹。
test命令的語(yǔ)法如下:
test expression
[命令的語(yǔ)法如下:
[ expression ]
字符串測(cè)試整數(shù)測(cè)試、
對(duì)于初學(xué)者來(lái)說(shuō),經(jīng)常犯的一個(gè)錯(cuò)誤就是錯(cuò)誤地使用運(yùn)算符。在進(jìn)行整數(shù)比較的時(shí)候,一定要是整數(shù)的運(yùn)算符。但是,由于受到其他程序設(shè)計(jì)語(yǔ)言的影響,初學(xué)者可能會(huì)使用字符串運(yùn)算符中的“=”和“!=”來(lái)進(jìn)行整數(shù)比較。
文件測(cè)試邏輯操作符條件判斷語(yǔ)句在Shell程序中,如果想要將多條命令放在同一行中,則需要使用分號(hào)將其隔開。
當(dāng)我們?cè)赟hell程序中使用代碼創(chuàng)建或者修改某個(gè)文件的時(shí)候,首先判斷一下文件是否創(chuàng)建成功,或者判斷文件是否存在是一個(gè)非常好的習(xí)慣。
在Shell中,還有一個(gè)特殊的命令,稱為空命令,其表示方法是一個(gè)冒號(hào)“:”,該命令不做任何事情,但是它的退出狀態(tài)永遠(yuǎn)是0。因此,如果我們將該命令作為if語(yǔ)句中的條件,則會(huì)永遠(yuǎn)執(zhí)行then子句,如下面的例子所示。
在實(shí)際的編程中,有人喜歡使用&&操作符來(lái)代替if語(yǔ)句,如下面的例子所示。
多條件判斷語(yǔ)句ca在上面的語(yǔ)法中,variable是一個(gè)變量,ca語(yǔ)句會(huì)將該變量的值與value1~valuen中的每個(gè)值相比較,如果與某個(gè)value的值相等,則執(zhí)行該value所對(duì)應(yīng)的一組語(yǔ)句。當(dāng)遇到“;;”符號(hào)時(shí),就跳出ca語(yǔ)句,執(zhí)行esac語(yǔ)句后面的語(yǔ)句。如果沒有任何一個(gè)值與variable的值相匹配,則執(zhí)行*后面的一組語(yǔ)句。
對(duì)于上面的ca語(yǔ)句,用戶應(yīng)該注意以下幾點(diǎn):
對(duì)于變量名variable,可以使用雙引號(hào),也可以不使用。每個(gè)ca子句中的條件測(cè)試部分,都以右括號(hào)“)”結(jié)束。每個(gè)ca子句都以一對(duì)分號(hào)“;;”作為結(jié)束符。在腳本執(zhí)行的過程中,當(dāng)遇到一對(duì)分號(hào)時(shí),會(huì)跳過當(dāng)前ca子句后面的所有的ca子句,包括*所對(duì)應(yīng)的子句,執(zhí)行esac子句后面的其他的語(yǔ)句。ca語(yǔ)句結(jié)構(gòu)以esac結(jié)尾。這與if語(yǔ)句以fi結(jié)尾是一樣的,都是以前面一個(gè)單詞的所有字母的逆序排列作為結(jié)束標(biāo)記運(yùn)算符執(zhí)行算術(shù)運(yùn)算可以通過4種方式來(lái)執(zhí)行算術(shù)運(yùn)算,這4種方式分別如下:
1、使用expr外部程序
expr expression
2、使用$((…))
3、使用$[…]
4、使用let命令
使用let命令可以執(zhí)行一個(gè)或者多個(gè)算術(shù)表達(dá)式,其中的變量名無(wú)需使用$符號(hào)。如果表達(dá)式中含有空格或者其他特殊字符,則必須將其引用起來(lái)。
位運(yùn)算符自增/自減運(yùn)算符循環(huán)結(jié)構(gòu)帶列表的for循環(huán)語(yǔ)句在上面的語(yǔ)法中,variable稱為循環(huán)變量,list是一個(gè)列表,可以是一系列的數(shù)字或者字符串,元素之間使用空格隔開。do和done之間的所有的語(yǔ)句稱為循環(huán)體,即循環(huán)結(jié)構(gòu)中重復(fù)執(zhí)行的語(yǔ)句。
除了將各個(gè)數(shù)字全部列出之外,用戶還可以使用另外一種比較簡(jiǎn)單的書寫方法,即用一個(gè)范圍來(lái)代替列出所有的元素。例如,上面的1~8所有的數(shù)字可以使用{1…8}來(lái)代替。
for語(yǔ)句的步長(zhǎng),即循環(huán)變量每次增加的值都是1。實(shí)際上,Shell允許用戶指定for語(yǔ)句的步長(zhǎng)。當(dāng)用戶需要另外指定步長(zhǎng)時(shí),其基本語(yǔ)法如下:
演示通過for循環(huán),并配合步長(zhǎng)來(lái)計(jì)算100以內(nèi)奇數(shù)的和,代碼如下:
在for循環(huán)的列表?xiàng)l件中,除了使用數(shù)字作為元素之外,還可以使用字符串。
本例將1周中7天的名字作為列表?xiàng)l件,依次輸出每天的名稱。代碼如下:
如果使用字符串作為列表元素,實(shí)際上可以省略外面的大括號(hào)。因此,可以修改為以下形式:
在前面的例子中的for循環(huán)里面,都是直接指定循環(huán)的條件列表。實(shí)際上,Shell中的for循環(huán)非常靈活,除了直接指定條件之外,還可以通過其他的方式來(lái)獲得條件列表。例如,某些Shell命令會(huì)輸出一個(gè)列表。其中,最常見的命令就是ls命令,該命令可以列出某個(gè)目錄下面的文件清單。
列表for循環(huán)還有一個(gè)比較重要的用途就是處理腳本的參數(shù)。前面講過,用戶可以通過系統(tǒng)變量“$*”一次獲取所有的參數(shù),并且,這些參數(shù)值之間是通過空格隔開的,所以,用戶同樣可以將該系統(tǒng)變量獲取的參數(shù)值作為for循環(huán)的條件列表,從而可以依次處理各個(gè)參數(shù)。
類C風(fēng)格的for循環(huán)語(yǔ)句在Linux或者UNIX上面,C或者C++是最主流的開發(fā)語(yǔ)言。因此,從事Linux系統(tǒng)管理的系統(tǒng)管理員也或多或少地接觸過C或者C++語(yǔ)言。通常來(lái)說(shuō),這些人對(duì)于C語(yǔ)言的語(yǔ)法比較熟悉。為了適應(yīng)這部分用戶的習(xí)慣,bash也提供了類C風(fēng)格的for循環(huán)語(yǔ)句。類C風(fēng)格的for循環(huán)語(yǔ)句的基本語(yǔ)法如下:
演示類C風(fēng)格的for循環(huán)語(yǔ)句的使用方法,代碼如下:
使用for循環(huán)語(yǔ)句處理數(shù)組
演示通過for循環(huán)來(lái)遍歷數(shù)組,代碼如下:
until循環(huán)語(yǔ)句在上面的語(yǔ)法中,expression是一個(gè)條件表達(dá)式。當(dāng)該表達(dá)式的值不為0時(shí),將執(zhí)行do和done之間的語(yǔ)句;當(dāng)expression的值為0時(shí),將退出until循環(huán)結(jié)構(gòu),繼續(xù)執(zhí)行done語(yǔ)句后面的其他語(yǔ)句。
while循環(huán)語(yǔ)句當(dāng)while循環(huán)結(jié)構(gòu)在執(zhí)行時(shí),會(huì)首先計(jì)算expression表達(dá)式的值,如果表達(dá)式的值為0,則執(zhí)行循環(huán)體中的語(yǔ)句;否則,退出while循環(huán),執(zhí)行done關(guān)鍵字后面的語(yǔ)句。當(dāng)循環(huán)體中的語(yǔ)句執(zhí)行完成之后,會(huì)重新計(jì)算expression的值,如果仍然是0,則繼續(xù)執(zhí)行下一次的循環(huán),直至expression的值為非0。
理解while語(yǔ)句與until語(yǔ)句的區(qū)別
這兩個(gè)語(yǔ)句的語(yǔ)法結(jié)構(gòu)非常相似,都是將循環(huán)條件放在語(yǔ)句的后面。
但是,在while語(yǔ)句中,當(dāng)expression的值為0時(shí)才執(zhí)行循環(huán)體中的語(yǔ)句,當(dāng)expression的值為非0值時(shí),將退出循環(huán)體;在until語(yǔ)句中,當(dāng)expression的值為非0時(shí),執(zhí)行循環(huán)體中的語(yǔ)句,當(dāng)expression的值為0時(shí),將退出循環(huán)結(jié)構(gòu)。因此,用戶在使用這兩種語(yǔ)句時(shí),一定要注意區(qū)分這個(gè)關(guān)鍵的地方。
在執(zhí)行機(jī)制方面,這兩個(gè)語(yǔ)句是相同的,即首先會(huì)判斷expression的值,當(dāng)該表達(dá)式的值符合要求時(shí),才執(zhí)行循環(huán)體中的語(yǔ)句;否則,都不會(huì)執(zhí)行循環(huán)體。
利用break和continue語(yǔ)句控制循環(huán)break:立即從循環(huán)中退出;
continue:而后者則用來(lái)跳過循環(huán)體中的某些語(yǔ)句,繼續(xù)執(zhí)行下一次循環(huán)。
本文發(fā)布于:2023-02-28 20:01:00,感謝您對(duì)本站的認(rèn)可!
本文鏈接:http://www.newhan.cn/zhishi/a/167764974876618.html
版權(quán)聲明:本站內(nèi)容均來(lái)自互聯(lián)網(wǎng),僅供演示用,請(qǐng)勿用于商業(yè)和其他非法用途。如果侵犯了您的權(quán)益請(qǐng)與我們聯(lián)系,我們將在24小時(shí)內(nèi)刪除。
本文word下載地址:shell語(yǔ)法(powershell語(yǔ)法).doc
本文 PDF 下載地址:shell語(yǔ)法(powershell語(yǔ)法).pdf
| 留言與評(píng)論(共有 0 條評(píng)論) |