本文是對Linux shell編程的一個學(xué)習(xí)比較,共包括如下章節(jié)的內(nèi)容:
- 概述
- 基本語法
- 結(jié)構(gòu)化語句
- 函數(shù)
- 小結(jié)
參考資料:一些常見的linux bash命令可參見《Linux常見Shell命令》梢什。
一甫煞、概述
(一)基本概念
Linux shell是系統(tǒng)的用戶界面,提供了用戶與內(nèi)核進行交互操作的一種接口沉馆。它接收用戶輸入的命令并把它送入內(nèi)核去執(zhí)行平项。
shell既是一種解釋器,也是一種編程語言悍及,我們除了可以在命令行下執(zhí)行單條的shell命令外闽瓢,如 echo , ls , cpd等命令。我們還可以編寫shell程序心赶,shell程序是一種腳本語言扣讼,同其它腳本語言一樣,shell程序支持變量缨叫、結(jié)構(gòu)化語句等特性椭符,我們可以將代碼保存到腳本文件中,后續(xù)調(diào)用執(zhí)行該腳本耻姥。
linux的shell和linux版本一樣销钝,有很多種,常見的如:
- Bourne Shell(/usr/bin/sh或/bin/sh)
- Bourne Again Shell(/bin/bash)
- C Shell(/usr/bin/csh)
- K Shell(/usr/bin/ksh)
- Shell for Root(/sbin/sh)
各種shell支持的命令和編程語言語法是類似的琐簇,但也有些細微的差別蒸健。這些shell類型中,其中最常用的是bash(即Bourne Again Shell)婉商,bash因為易用和免費似忧,Bash 在日常工作中被廣泛使用。同時丈秩,Bash 也是大多數(shù)Linux 系統(tǒng)默認(rèn)的Shell盯捌。
當(dāng)我們在Linux系統(tǒng)本機或遠程打開一個linux控制臺后,會自動運行默認(rèn)的shell程序蘑秽,出現(xiàn)交互式界面饺著,我們可以通過echo $0 來查看當(dāng)前運行的是哪種shell。如下面例子:
$ echo $0
-bash
上面例子顯示肠牲,我們使用的是bash類型幼衰。
在本文,我們介紹的是bash埂材。
(二)shell腳本
下面我們來看下如何編寫和執(zhí)行一個shell腳本文件塑顺。
1、新建一個文本文件
文件名可以是任意合法的文件名,擴展名習(xí)慣為sh严拒,當(dāng)然也可以沒有擴展名扬绪。我們這里假設(shè)文件名為test.sh。
文件內(nèi)容如下:
#!/bin/bash
echo hello
上面例子的腳本文件就兩行裤唠,第一行是個特殊語句挤牛,#! 是一個約定的標(biāo)記,它告訴系統(tǒng)這個腳本需要什么解釋器來執(zhí)行种蘸,即使用哪一種 Shell墓赴,我們這里是使用bash。所有的shell腳本都必須有這一行內(nèi)容航瞭。
后面的內(nèi)容就可以是命令了诫硕,我們這里只有一行命令,即echo命令刊侯。這樣執(zhí)行該腳本章办,會在控制臺輸出hello內(nèi)容。
2滨彻、設(shè)置可執(zhí)行權(quán)限
腳本要想當(dāng)作可執(zhí)行文件被運行藕届,需要設(shè)置權(quán)限,如下方式:
chmod +x ./test.sh
使用chmod命令使test.sh文件變?yōu)榭蓤?zhí)行程序亭饵。
3休偶、執(zhí)行
在shell提示符下運行 ./test.sh ,就可以執(zhí)行該腳本辜羊。
在bash腳本中踏兜,除#!這個外,所有#后面的內(nèi)容都會被當(dāng)作注釋內(nèi)容只冻,執(zhí)行時會被忽略庇麦,如下面腳本:
#!/bin/bash
echo hello #輸出hello信息
#定義shell變量
myid=100
#輸出變量內(nèi)容
echo $myid
上面腳本中,第一行#!打頭的用于指定shell類型喜德,后面的#都是用來書寫注釋信息的。
shell腳本程序?qū)嶋H是由一條條的命令和結(jié)構(gòu)化語句組成垮媒,我們可以把這一條條的shell命令調(diào)用看作其它編程語言的函數(shù)調(diào)用舍悯,另外bash也支持定義函數(shù)。linux系統(tǒng)常見的shell命令可參考《Linux常見Shell命令》睡雇。
(三)腳本參數(shù)
在編寫shell腳本程序時萌衬,很多情況下程序需要獲取一些用戶輸入的信息,這有兩種方式它抱,一種是在腳本中使用read命令秕豫,當(dāng)腳本執(zhí)行到read命令時,會停下等待用戶輸入后才會繼續(xù)執(zhí)行;但在很多時候混移,腳本往往被自動執(zhí)行祠墅,不適合用戶輸入,這個可以通過調(diào)用腳本時給腳本傳入?yún)?shù)來實現(xiàn)歌径,這種場景往往更多毁嗦。
下面我們來介紹如何給腳本傳參數(shù)。
在執(zhí)行 Shell 腳本時回铛,向腳本傳遞參數(shù)狗准,腳本內(nèi)獲取參數(shù)的格式為:$n。n 代表一個數(shù)字茵肃,1 為執(zhí)行腳本的第一個參數(shù)腔长,2 為執(zhí)行腳本的第二個參數(shù),以此類推……验残。另外$0 為執(zhí)行的文件名捞附。
下面舉例說明:
假設(shè)腳本文件名為test.sh,文件內(nèi)容如下:
#!/bin/bash
echo $0
echo $1
echo $2
執(zhí)行如下的命令:
$ ./test.sh tom 20
./test.sh
tom
20
可以看出胚膊,我們在調(diào)用test.sh傳入了兩個參數(shù)tom和20故俐,在腳本程序中通過2獲取到傳入的參數(shù),并且通過$0獲取到文件名紊婉。
為了簡單药版,本文下面的例子演示沒有寫到腳本文件中進行調(diào)用執(zhí)行,而是直接在控制臺$符號下進行的喻犁。
二槽片、基本語法
(一)shell變量
變量是任何一門編程語言中的基本特性,變量用于保存值肢础。Linux shell同樣支持變量还栓。在shell腳本中,可以創(chuàng)建變量传轰,shell腳本中的變量只在創(chuàng)建它的shell中使用剩盒。shell中的變量創(chuàng)建和賦值放在一起,不需要使用任何關(guān)鍵字慨蛙,只需”變量名=變量值”即可辽聊。特別要注意的是,=兩邊不能有空格期贫。
使用變量時跟匆,通過$符號來引用。如下面示例:
$ x=hello
$ echo $x
hello
$ y=12
$ echo $y
12
需要注意的是通砍,上面例子中以符號是shell終端的提示符,該行語句表示執(zhí)行一條命令。沒有$開頭行的是命令執(zhí)行的輸出內(nèi)容迹冤。后面的例子一樣讽营。
上面示例代碼中,第1行定義了變量x叁巨,其值為hello斑匪。第2行執(zhí)行echo命令在控制臺輸出變量x的值,可以看出锋勺,引用變量時要在變量名前加$符號蚀瘸。第3行定義了變量y,第4行調(diào)用echo命令輸出變量y的值庶橱。
shell是一種腳本語言贮勃,弱類型的,定義變量時不需要聲明數(shù)據(jù)類型苏章。賦值給變量的值全部會當(dāng)作字符串處理寂嘉。值可以用雙引號或單引號括起來,也可以不用(如上面例子沒有用引號括起)枫绅,如下面例子:
$ x="hello"
$ echo $x
hello
$ x='hello"world'
$ echo $x
hello"world
上面例子中泉孩,給變量賦值時,值用引號括起來并淋。
需要注意的是寓搬,在shell中,標(biāo)識符(如變量名)是區(qū)分大小寫的县耽。
(二)環(huán)境變量
Linux下的環(huán)境變量與windows下的的環(huán)境變量類似句喷。當(dāng)linux內(nèi)核啟動一個程序時,內(nèi)核會將一個包含字符串?dāng)?shù)組的列表傳遞給程序兔毙,這個列表稱為命令執(zhí)行環(huán)境唾琼,簡稱為環(huán)境,以name=value格式保存了一系列名/值對澎剥。
在bash中锡溯,我們可以使用這些環(huán)境變量。
linux中的環(huán)境變量分為持久和臨時的哑姚,持久的環(huán)境變量是在文件中保存的趾唱,因為是持久化的,所以永久有效蜻懦;而臨時的環(huán)境變量只在內(nèi)存中,只針對當(dāng)前shell會話有效夕晓。
下面我們先看下如何定義臨時的環(huán)境變量宛乃。通過export命令可以定義環(huán)境變量。如下面例子:
$ export myid=100
$ echo $myid
100
上面例子第一句定義了環(huán)境變量myid,該變量的值為100征炼,注意等號兩邊不能有空格析既。使用環(huán)境變量和使用shell變量一樣,用$加前綴引用谆奥。
在上一節(jié)我們介紹了shell變量的使用眼坏,那與環(huán)境變量有啥區(qū)別呢?我們通過例子來說明:
$ myid=100
$ echo $myid
100
$ bash
$ echo $myid
$
上面例子酸些,我們先定義了一個shell變量myid宰译,然后我們在當(dāng)前會話下運行bash程序(相當(dāng)于啟動了一個子shell),會發(fā)現(xiàn)在這子shell中魄懂,無法獲取到父shell中定義的變量沿侈。
我們看下如果定義成環(huán)境變量會如何?如下面例子:
$ export myid=100
$ echo $myid
100
$ bash
$ echo $myid
100
$
可以看出市栗,定義成環(huán)境變量后缀拭,在子shell中就可以使用。
需要說明的是填帽,當(dāng)在控制臺執(zhí)行一個shell腳本文件時蛛淋,相當(dāng)于啟動一個子shell,這意味著無法在shell文件中引用外部定義的shell變量篡腌,但可以使用環(huán)境變量褐荷。
下面我們來看下如何持久化環(huán)境變量,即將環(huán)境變量的設(shè)置信息保存在文件中哀蘑。Linux中環(huán)境變量包括系統(tǒng)級和用戶級诚卸,系統(tǒng)級的環(huán)境變量是每個登錄到系統(tǒng)的用戶都要讀取的系統(tǒng)變量,而用戶級的環(huán)境變量則是該用戶使用系統(tǒng)時加載的環(huán)境變量绘迁。 所以linux保存環(huán)境變量的文件也分為系統(tǒng)級和用戶級的合溺。
持久化環(huán)境變量,很簡單缀台,只需將export命令寫入到相應(yīng)的配置文件中棠赛。需要說明的是,不同版本的linux系統(tǒng)膛腐,所使用的配置文件可能不同睛约,而且這些配置文件還存在相互調(diào)用的問題。
用戶登陸時哲身,會先執(zhí)行/etc/profile腳本文件中的命令辩涝,為全系統(tǒng)所有用戶建立環(huán)境變量。我們可以在該文件中設(shè)置一些對所有用戶都有關(guān)的環(huán)境變量勘天。需要注意的是怔揩,如果修改了該文件中的內(nèi)容捉邢,需要重啟系統(tǒng)才能生效。
每個用戶特有的環(huán)境變量商膊,在該用戶的主目錄下的腳本中設(shè)置伏伐。如.bash_profile腳本文件,該文件會調(diào)用.bashrc腳本文件晕拆,而.bashrc又會調(diào)用/etc/bashrc腳本文件藐翎。我們可以在.bash_profile或.bashrc中設(shè)置本用戶特有的環(huán)境變量。每次打開shell实幕,.bash_profile都會被執(zhí)行吝镣。如果修改了.bash_profile或.bashrc文件中的內(nèi)容,需要退出當(dāng)前shell重新打開shell才能生效茬缩。
用戶主目錄下還有一個腳本文件.bash_logout赤惊,當(dāng)用戶退出當(dāng)前shell時,該腳本會被執(zhí)行凰锡,可以在該腳本中進行一些資源釋放操作未舟。
(三)運算符與表達式
表達式是將常量、變量掂为、運算符組合在一起番川,產(chǎn)生一個值昂勒。在本小節(jié)我們來介紹算術(shù)運算喷屋。bash支持的算術(shù)運算符和其它語言差不多苏研,包括 +(加)、-(減)欲诺、*(乘)抄谐、/(整除)、%(取余)
在bash中扰法,與其它語言不同蛹含,如下的操作是無法進行算術(shù)運算的,如:
$ a=2+3
$ echo $a
2+3
$ a=2 + 3
bash: +: 未找到命令...
上面例子塞颁,直接數(shù)字相加不是一個表達式浦箱,如果+兩邊無空格,則會被當(dāng)作一個字符串祠锣;如果+兩邊有空格酷窥,則會報錯。
我們再看下伴网,有變量參與的情況蓬推,例子如下:
$ a=2
$ b=$a+2
$ echo $b
2+2
$ b=$a + 3
bash: +: 未找到命令...
從執(zhí)行情況看,與常量運算差不多澡腾,依然無法進行計算拳氢。
在bash中募逞,算術(shù)表達式需要有些特殊的寫法,第一種方式是利用expr表達式馋评,如下面例子:
$ echo `expr 2 + 2`
4
$ a=3
$ echo `expr $a + 2`
5
也就是說要在表達式前加expr關(guān)鍵字,并將整個內(nèi)容放在倒引號之中刺啦,這才是一個合法的算術(shù)表達式留特。另外要特別注意的是,運算符左右要有空格玛瘸,沒有空格就不會被計算蜕青,如下面例子:
$ echo `expr 2+2`
2+2
可以看出,上面例子+左右無空格糊渊,被當(dāng)作了一個字符串右核。這使用起來比較別扭。
還有一種方式是渺绒,使用 $[表達式] 這樣的方式贺喝,如:
$ echo $[3+5]
8
采用$[]方式的好處是,運算符宗兼,如上面的+左右可以有空格躏鱼,也可以沒空格,這個與其它編程語言一樣殷绍,用起來就不容易出錯染苛。
另外使用符號茶行,這樣就與其它編程語言中的算術(shù)表達式類似,如下面例子:
$ a=12
$ echo $[a-4]
8
$ echo $[a*a]
144
通過內(nèi)置命令let可以將一個表達式賦值給一個變量登钥,變量的值就是表達式的計算結(jié)果畔师,如下面例子:
$ let x=12+14
$ echo $x
26
上面例子,通過內(nèi)置命令let將一個算術(shù)表達式賦值給了一個變量x怔鳖≤园Γ可以看出,變量的值就是表達式的計算結(jié)果结执。需要注意的是度陆,=和+兩邊都不能有空格。
從上面幾種算術(shù)表達式的編寫方式看献幔,還是使用$[]格式最好懂傀,不需要關(guān)心是否有空格等問題。
需要注意的是:標(biāo)準(zhǔn)的bash只支持整數(shù)運算蜡感,不支持浮點運算蹬蚁,如下面例子:
$ echo $[12+12]
24
$ echo $[12+12.5]
-bash: 12+12.5: 語法錯誤: 無效的算術(shù)運算符 (錯誤符號是 ".5")
可以看出恃泪,上面的表達式中有浮點數(shù)12.5,會報錯犀斋。如果想要支持浮點運算贝乎,需要使用特殊的第三方包,這里不再介紹叽粹。
(四)字符串連接
連接字符串是個常見的操作览效,不同于很多編程語言,通過+運算符可以將字符串連接虫几,在bash中锤灿,連接字符串的方式如下:
$ x=hello
$ y=world
$ z=${x}${y}
$ echo $z
helloworld
從上面例子可以看出,連接字符串時辆脸,用{}將變量名括起但校,注意$符號要放在{}外邊。下面再看一個將變量與常量連接的例子:
$ x=hello
$ z=${x}world
$ echo $z
helloworld
(五)數(shù)組
bash支持一維數(shù)組啡氢,將多個空格分開的值放在()可定義數(shù)組状囱,利用下標(biāo)(從0開始)可獲取數(shù)組的中等個元素。如下面例子:
$ arr=(a b c)
$ echo ${arr[0]}
a
$ echo ${arr[2]}
c
上面例子空执,先定義了一個數(shù)組arr浪箭,然后利用 ${數(shù)組名[序號]} 這樣的方式來獲取數(shù)組中的元素。
我們還可以利用下標(biāo)來新建元素或往元素中添加元素辨绊,如:
myarr[0]=1
上面語句奶栖,如果myarr數(shù)組不存在,則會新建一個數(shù)組门坷,并添加一個元素宣鄙。如果已經(jīng)存在,且指定序號的元素存在默蚌,則會替換冻晤,bash中的元素序號可以不連續(xù),如:
myarr[5]=2
利用@或*做下標(biāo)可以獲取所有數(shù)組的內(nèi)容绸吸,如下面例子:
$ data=( 2 4)
$ echo ${data[*]}
2 4
$ echo ${data[@]}
2 4
獲取數(shù)組長度的語法是 ${#數(shù)組名{*}}鼻弧,如:
echo ${#data[*]}
三、結(jié)構(gòu)化語句
(一)條件表達式
條件表達式主要用于if條件語句和循環(huán)語句中锦茁。
bash的條件表達式有如下寫法攘轩,一種是使用[]的條件表達式,如下面例子:
a=3
b=4
if [ $a == $b ]
then
echo a==b
else
echo a!=b
fi
上面例子中[]之間是一個條件表達式码俩,==是判斷是否相等的運算符度帮。需要注意的是,[]內(nèi)部的兩邊必須要有空格稿存,運算符==的兩邊也必須要有空格笨篷。這是使用bash編寫程序比較別扭和需要注意的地方瞳秽。
下表列出了bash常用的關(guān)系運算符,假定變量 a 為 3率翅,變量 b 為 4:
運算符 | 說明 | 舉例 |
---|---|---|
== | 檢測兩個數(shù)是否相等练俐,相等返回 true。 | b 返回false |
!= | 檢測兩個數(shù)是否不相等安聘,相等返回 true痰洒。 | b 返回true |
-eq | 檢測兩個數(shù)是否相等,相等返回 true浴韭。等同于== | [ b ] 返回 false。 |
-ne | 檢測兩個數(shù)是否不相等脯宿,不相等返回 true念颈。等同于!= | [ b ] 返回 true。 |
-gt | 檢測左邊的數(shù)是否大于右邊的连霉,如果是榴芳,則返回 true。 | [ b ] 返回 false跺撼。 |
-lt | 檢測左邊的數(shù)是否小于右邊的窟感,如果是,則返回 true歉井。 | [ b ] 返回 true柿祈。 |
-ge | 檢測左邊的數(shù)是否大于等于右邊的,如果是哩至,則返回 true躏嚎。 | [ b ] 返回 false。 |
-le | 檢測左邊的數(shù)是否小于等于右邊的菩貌,如果是卢佣,則返回 true。 | [ b ] 返回 true箭阶。 |
bash也支持邏輯運算符虚茶,對兩個布爾值進行運算,其中 -a 用于“與”運算仇参;-o用于“或”運算嘹叫;-o用于“非”運算,如下面例子:
a=3
b=4
if [ $a -lt 5 -a $b -gt 2 ]
then
echo "a 小于 5 且 b 大于 2 "
fi
bash也支持字符串的布爾運算冈敛。下表列出了常用的字符串運算符待笑,假定變量 a 為 "abc",變量 b 為 "efg":
運算符 | 說明 | 舉例 |
---|---|---|
= | 檢測兩個字符串是否相等抓谴,相等返回 true暮蹂。 | [ b ] 返回 false寞缝。 |
!= | 檢測兩個字符串是否相等,不相等返回 true仰泻。 | [ b ] 返回 true荆陆。 |
-z | 檢測字符串長度是否為0,為0返回 true集侯。 | [ -z $a ] 返回 false被啼。 |
-n | 檢測字符串長度是否為0,不為0返回 true棠枉。 | [ -n "$a" ] 返回 true浓体。 |
$ | 檢測字符串是否為空,不為空返回 true辈讶。 | [ $a ] 返回 true命浴。 |
在shell編程中,經(jīng)常要對文件進行操作贱除。bash提供了很多運算符進行文件的相關(guān)測試生闲。相關(guān)運算符如下:
- -e 文件名 如果文件存在則為真
- ** -r 文件名 如果文件存在且可讀則為真**
- -w 文件名 如果文件存在且可寫則為真
- -x 文件名 如果文件存在且可執(zhí)行則為真
- -s 文件名 如果文件存在且至少有一個字符則為真
- -d 文件名 如果文件存在且為目錄則為真
- -f 文件名 如果文件存在且為普通文件則為真
- -c 文件名 如果文件存在且為字符型特殊文件則為真
- -b 文件名 如果文件存在且為塊特殊文件則為真
下面看一個例子:
if [ -e test.txt ]
then
echo test.txt is exist
fi
上面代碼測試了當(dāng)前目錄下是否存在test.txt文件。
除了使用[]來表示條件表達式外月幌,還可以使用test命令碍讯。test是bash的內(nèi)置命令,test命令用于檢查某個條件是否成立扯躺,它可以進行數(shù)值捉兴、字符和文件三個方面的測試,如果成立(即為真)缅帘。如下面例子:
a=3
b=4
if test $a == $b
then
echo a==b
else
echo a!=b
fi
對于數(shù)值判斷轴术,還支持通過(())來進行條件描述,并支持 > 钦无,>= 等運算符逗栽,這些運算符[]和test命令不支持,如下面例子:
int=1
while(($int<=5))
do
echo $int
int=$[int+1]
done
使用(())這種寫法失暂,運算符彼宠,如上面的<=左右是否有空格無所謂。
(二)if語句
bash中的if條件語句弟塞,除細微的語法細節(jié)不同外凭峡,和c,java語言的if語句基本類似决记。其基本語法格式如下:
if 條件
then
命令...
fi
如果條件為真摧冀,則會執(zhí)行then后的命令(可以有1條或多條命令),if語句以fi結(jié)尾。
除 if...then...fi語句外索昂,bash還支持 if ...then...else..fi語句建车,即當(dāng)if后的條件為真,執(zhí)行then后的語句椒惨,否則執(zhí)行else后的語句缤至。
另外還支持 if ..then..[elif ..then]..else..fi 語句,可以有1個或多了elif語句康谆。
因為if語句的語法和其它編程語言類似领斥,上面小節(jié)也有舉例了,所以不再詳細介紹沃暗。
(三)case語句
類似c,java中的case語句月洛,用于支持多條件匹配,其語法格式如:
case 值 in
匹配值1)
command1
command2
...
commandN
;;
...
匹配值n)
command1
command2
...
commandN
;;
esac
上面語法有如下要求:
1)case和in之間的值可以是常量或變量
2)每個匹配值后面跟著)右括號
3)某個匹配值被匹配孽锥,其后的命令被執(zhí)行膊存,直至碰到;; (相當(dāng)于其它語言中的break)。需要說明的是忱叭,被匹配的到分支,一定要有;;x
4)如果想匹配任意值今艺,匹配值可寫成*韵丑,一般放到最后
5)最后整個case語句需要用esac結(jié)尾(即case單詞反過來寫)。
下面我們看一個具體的例子:
num=2
case $num in
1) echo 'num = 1'
;;
2) echo 'num = 2'
;;
3) echo 'num = 3'
;;
4) echo 'num = 4'
;;
*) echo 'num = other'
;;
esac
執(zhí)行上面代碼虚缎,發(fā)現(xiàn)會輸出2.
(四)for循環(huán)
bash支持for循環(huán)撵彻,有如下用法.
1、遍歷多個值实牡,如:
$ for v in a b c
> do
> echo $v
> done
a
b
c
上面例子用到了for in do done 四個關(guān)鍵字陌僵,in后面跟的是要遍歷的列表值,for和in之間是用于代表每次循環(huán)元素创坞,執(zhí)行的命令需要位于 do和done之間碗短。
說明:上面的for語句有換行時,>是控制臺自動顯示的內(nèi)容题涨。如果是在腳本中編寫偎谁,則沒有>符號。也可以寫在一行纲堵,采用如下格式:
for v in a b c; do echo $v; done
2巡雨、遍歷數(shù)組
可以用for語句來遍歷數(shù)組,如下面例子:
$ for v in ${arr[*]}
> do
> echo $v
> done
3
6
12
3席函、c語言的風(fēng)格
也支持類似c語言的for循環(huán)風(fēng)格铐望,如下面例子:
$ for((i=1;i<=5;i++))
> do
> echo $i
> done
1
2
3
4
5
注意,for后面的內(nèi)容是用兩個小括號包圍的。
(五)while循環(huán)
類似c,java中的while語句正蛙,滿足條件執(zhí)行循環(huán)中的內(nèi)容督弓。如下面例子:
int=1
while [ $int -le 5 ]
do
echo $int
int=$[int+1]
done
或改為(())的條件寫法
int=1
while(( $int<=5 ))
do
echo $int
let int=int+1hu
done
注意,while后面的條件表達式要放在兩個()之間跟畅。
同樣我們可以使用test內(nèi)置命令來作為條件咽筋,如:
int=1
while test $int -le 5
do
echo $int
let int=int+1
done
(六)break和continue語句
類似c,java中的break和continue,可以跳出循環(huán)徊件,或提前結(jié)束本次循環(huán)奸攻。下面看具體例子:
int=1
while [ $int -le 5 ]
do
if (( $int==3 ))
then
break
fi
echo $int
int=$[int+1]
done
上面代碼執(zhí)行,只會輸出1,2信息虱痕。
再看一個continue的例子:
int=0
while [ $int -le 5 ]
do
int=$[int+1]
if (( $[int%2]==0 ))
then
continue
fi
echo $int
done
上面代碼執(zhí)行睹耐,只會輸出1,3,5信息。
四部翘、函數(shù)
(一)基礎(chǔ)
bash支持定義函數(shù)硝训,其語法格式為:
[ function ] 函數(shù)名 ()
{
命令
[return 整數(shù)]
}
上面語法有如下特點:
1)關(guān)鍵字function可選
2)return語句可選,return后面跟0~255的整數(shù)值新思,作為函數(shù)返回值窖梁。如果無return語句,則以最后一條命令運行結(jié)果作為返回值夹囚。
下面我們通過具體的例子來說明纵刘。我們先來看一個最簡單的例子,如:
myfun()
{
echo "this is a fun"
}
上面定義了一個函數(shù)荸哟,函數(shù)名為myfun假哎。
調(diào)用函數(shù)就同調(diào)用shell命令類似,注意不像其它語言鞍历,調(diào)用時不能加()舵抹,如:
$ myfun
this is a fun
上面在$提示符下直接輸入myfun就是調(diào)用函數(shù)。
(二)函數(shù)的返回值
我們先看下shell命令執(zhí)行的返回值劣砍,bash中的每條命令執(zhí)行后都會有一個返回值惧蛹,一般情況下成功返回值為0,出錯的話返回值就是一個非0整數(shù)秆剪。命令執(zhí)行的返回值赊淑,通過在命令執(zhí)行后使用$?來獲取。
如下面例子:
$ ls test.txt
test.txt
$ echo $?
0
$ ls test5.txt
ls: 無法訪問test5.txt: 沒有那個文件或目錄
$ echo $?
2
$ ls test.txt
test.txt
$ echo $?
0
從上面例子我們可以看出仅讽,先使用ls命令顯示一個正確的文件后陶缺,$?的值為0,這是命令返回結(jié)果洁灵;然后用ls命令顯示不存在的文件饱岸,ls命令會報錯掺出,這時$?的值為非零值。
bash函數(shù)的調(diào)用苫费,和執(zhí)行shell命令類似汤锨,其返回值也是通過$?來獲取的,這點與其它編程語言差別很大百框。
前面我們提到闲礼,在函數(shù)中通過可選的return語句,后面跟0~255的整數(shù)值铐维,作為函數(shù)返回值柬泽。如果無return語句,則以最后一條命令運行結(jié)果作為返回值嫁蛇。
下面我們通過例子來說明:
$ myfun()
> {
> echo "this is a fun"
> return 100
> }
$ myfun
this is a fun
$ echo $?
100
上面例子我們先定義了一個函數(shù)myfun锨并,然后調(diào)用該函數(shù),最后顯示$?的值睬棚,這個值就是myfun函數(shù)中的return后面的值第煮。
下面我們再看一個無return語句的例子,如:
$ myfun()
> {
> rm other.txt
> echo hello
> }
$ myfun
rm: 無法刪除"other.txt": 沒有那個文件或目錄
hello
$ echo $?
0
上面例子中定義的myfun函數(shù)中有兩條命令抑党,調(diào)用函數(shù)時包警,rm命令報錯,echo命令正常執(zhí)行底靠,所以調(diào)用函數(shù)后獲取到的$?的值為0揽趾。如果我們試著把這兩個命令順序換下,會發(fā)現(xiàn)$?的值不為0苛骨,這里不再具體的演示。
(三)函數(shù)的參數(shù)
Bash的函數(shù)也可以有參數(shù)苟呐,但參數(shù)的使用方法和別的編程語言有較大差別痒芝,c/java等編程語言的函數(shù)參數(shù)是在函數(shù)聲明中定義,而bash函數(shù)的參數(shù)由調(diào)用時決定牵素。
在調(diào)用bash函數(shù)時严衬,可以向其傳遞參數(shù)。在函數(shù)體內(nèi)部笆呆,通過 $n 的形式來獲取參數(shù)的值请琳,例如,$1表示第一個參數(shù)赠幕,$2表示第二個參數(shù)俄精,下面我們通過例子來說明:
$ myfun()
> {
> echo $1
> echo $2
> }
$ myfun hello 2
hello
2
上面代碼中函數(shù)myfun通過$1和$2引用了兩個函數(shù)參數(shù),調(diào)用函數(shù)時榕堰,傳入了2個參數(shù)竖慧,正好對應(yīng)$1和$2.
如果我們調(diào)用時不傳入?yún)?shù)值嫌套,則函數(shù)內(nèi)的$n的值為空。
結(jié)合前面所學(xué)的圾旨,可以看出踱讨,給函數(shù)傳遞參數(shù)和給腳本文件傳遞參數(shù)適用方式類似。
五砍的、小結(jié)
本文是對linux shell編程的一個學(xué)習(xí)總結(jié)痹筛,linux shell是一種腳本語言,具有腳本語言的一些基本特征廓鞠,如弱類型帚稠、解釋執(zhí)行,對變量诫惭、結(jié)構(gòu)化語句的支持等翁锡,也有一些差異化的語法特點。