對(duì)于Linux平臺(tái)下的開發(fā)者和維護(hù)人員來說,Shell編程是必須要掌握的一個(gè)知識(shí)點(diǎn)。通過Shell腳本能夠?qū)⑹謴?fù)雜的操作進(jìn)行簡化,從而大大的提高我們工作效率。
什么是Shell?
實(shí)際上,Shell是一個(gè)比較寬泛的概念,它可以有多種含義。比如,一個(gè)終端或命令行軟件我們可以稱為Shell,實(shí)際上它就是一個(gè)應(yīng)用程序,是人與系統(tǒng)進(jìn)行交互的一個(gè)操作界面;它也是一種程序語言或者命令語言,可以通過它編譯一系列的腳本。
作為Shell終端軟件來說,它實(shí)際上也是屬于泛指。之所以這么說是因?yàn)镾hell終端軟件也有多種。不過,基本上所有的Linux和大多數(shù)的Mac OS X里默認(rèn)用的都是Bourne Again Shell,也就是平時(shí)我們說的bash。它早在1987年由Brian Fox開發(fā)。
除bash之外,還有其他的Shell應(yīng)用程序:
Shell應(yīng)用程序
然而,今天我們要學(xué)習(xí)的實(shí)際上是在Shell上執(zhí)行的腳本語言,所以我們說Shell腳本編程。由于它是一種解釋性語言,Shell腳本編程不需要額外的安裝編譯器,它可以直接用編輯器直接編輯,然后直接在Shell上直接運(yùn)行即可。通常,我們?cè)诰帉懩_本時(shí),在第一行需要用#!來指定解釋器來運(yùn)行Shell腳本,比如,#!/bin/sh。
下面我們將為大家從如下幾個(gè)方面全面系統(tǒng)的為大家梳理Shell編程的相關(guān)知識(shí)點(diǎn)。
Shell編程
輸入輸出
shell中有兩種輸出命令:echo和printf。學(xué)習(xí)程序,生硬的文字始終沒有代碼來的直接易懂。我們就直接通過例子來學(xué)習(xí)吧。
echo "hello world"
printf "%s %s" "hello" "world"
printf "!!!n"
output
從上面的例子很容易發(fā)現(xiàn),echo命令默認(rèn)帶有換行符的,而printf則不是。與C語言中類似,printf是可以進(jìn)行格式化輸出的,其中,%s就是格式控制符,還有%c %d %f等控制符。另外,還可以通過在控制符中添加數(shù)字來制定字符的長度,比如,%3s表示三個(gè)字符長度;%4.3f表示4位整數(shù),3位小數(shù)。
#!/bin/sh
printf "%6s %3s %4s %5sn" 公司名 評(píng)級(jí) 銷售額 市場(chǎng)占比
printf "%6s %3c %4d %5fn" 公司A A 5001 0.5001
printf "%6s %3c %4d %5fn" 公司B C 1999 0.1999
printf "%6s %3c %4d %5fn" 公司B B 3000 0.3
printf
如果需要字符對(duì)齊,還可以使用-進(jìn)行字符左對(duì)齊,省略不加默認(rèn)右對(duì)齊。
在shell中是使用read命令作為輸入,它可以接受標(biāo)準(zhǔn)鍵盤的輸入;除此之外,也可以作為文件描述符的輸入,對(duì)文件進(jìn)行操作。
read命名的格式如下:
read [選項(xiàng)名] [變量名]
read命令在執(zhí)行時(shí),會(huì)將輸入的數(shù)據(jù)放到變量中,通常,我們會(huì)指定一個(gè)自定義的變量,如果不指定變量的話,則就會(huì)把輸入的數(shù)據(jù)保存到REPLY變量中。關(guān)于變量的一些具體信息可以在下面的變量章節(jié)了解。
read命令的選項(xiàng)名有下面幾種參數(shù),我們可以選擇一種或幾種進(jìn)行設(shè)置。
- -p:設(shè)置提示信息,屏幕會(huì)輸出提示信息;
- -t:設(shè)置等待時(shí)間(秒),等待用戶輸入的時(shí)間;
- -n:設(shè)置接收指定的字符數(shù);
- -s:隱藏輸入的數(shù)據(jù),用于比較隱私機(jī)密信息的輸入。
具體的使用方法大家可以參考下面的例子:
#!/bin/sh
read -p "input a name:" name
read -p "input a password:" -s passwd
echo ""
echo $name
echo $passwd
read
注釋
每種語言都少不了注釋,對(duì)于Shell也是一樣。一個(gè)好的注釋可以讓代碼更容易閱讀和維護(hù)。shell腳本里也可以使用兩種注釋:單行注釋和多行注釋。單行注釋可以直接在所在行使用#,多行注釋就需要:<<!和!。
# 這是一行內(nèi)容
# 這是一行內(nèi)容
:<<!
這是一行內(nèi)容
這是一行內(nèi)容
!
對(duì)于多行注釋除了用!符號(hào)外,還可以用EOF '等符號(hào)。
除了這兩種方法之外,還可以通過條件語句來實(shí)現(xiàn)。
變量
Shell可以定義變量,并通過=給變量賦值,與其他語言不同的是,在=和變量及被賦的值之間不能有空格。習(xí)慣了其他語言的同學(xué)可能會(huì)有些不適應(yīng),不過要注意這一點(diǎn)。
對(duì)于命名的規(guī)則,其實(shí)是與其他語言是類似的:
- 使用英文字母,數(shù)字和下劃線,但不能以數(shù)字開頭。
- shell的保留關(guān)鍵字不可以使用
v1=1234 #正確
v2="hello" #正確
v3_1="world" #正確
v4_1 = "world" #錯(cuò)誤,‘=’符前后不能有空格
除此之外,在訪問變量時(shí)需要在變量前$符來訪問,如果需要區(qū)分變量的邊界,還需要在變量前后加上{}用來區(qū)分變量名的邊界,建議在使用變量時(shí)加上{}。
a="hell world:"
b="一個(gè)敲代碼的廚子"
echo ${a}$
Shell的數(shù)據(jù)類型比較簡單,變量的默認(rèn)數(shù)據(jù)類型是字符串類型。我們可以使用單引號(hào)或雙引號(hào),因此,也是可以不用引號(hào)的。
我們?cè)賮砜匆粋€(gè)例子:
a=1
b=2
echo ${a}+$
大家覺得最后應(yīng)該輸出多少呢?
example
答案是不是超出了大家的預(yù)料?這樣大家應(yīng)該理解了為什么說Shell定義變量時(shí)默認(rèn)是字符串類型。
那么問題來了,該怎么表示數(shù)字呢?其實(shí),這里我們稍微進(jìn)行特殊處理一下就可以了,在數(shù)據(jù)運(yùn)算的時(shí)候我們用$[運(yùn)算表達(dá)式]形式就可以了。
a=1
b=2
echo $[${a}+$]
a+b
除了這種方法,還有其他的方法可以進(jìn)行數(shù)據(jù)運(yùn)算,我們?cè)诤竺娴臄?shù)據(jù)運(yùn)算章節(jié)在詳細(xì)展開,我們接著說變量。
我們可以將變量分成局部變量和環(huán)境變量:
- 局部變量:是在Shell命令或腳本中定義的變量,只能在當(dāng)前Shell命令或腳本中有效。
- 環(huán)境變量:創(chuàng)建它們的shell及其派生出來的任意子進(jìn)程中使用等。它可以保證一些程序的正常運(yùn)行。
在一些特殊的場(chǎng)景,我們不希望我們定義的變量數(shù)值被改變,這時(shí),我們可以使用readonly命令將變量設(shè)置成只讀。
a="hello world"
readonly a
echo ${a}
a="hahah"
還有一些場(chǎng)景需要清除一個(gè)變量,我們可以使用unset命令將變量刪除,需要注意的是對(duì)于只讀變量是不能刪除的。
a="hello world"
b="一個(gè)敲代碼的廚子"
readonly b
unset a
unset b
echo ${a}
echo $
字符串變量操作
了解了上面變量的內(nèi)容之后,我們知道變量模式是字符串類型的。那字符串的操作有哪些呢?
一般我們可以會(huì)對(duì)字符串變量進(jìn)行如下操作:
- 獲取字符串的長度:可以變量前加上#符號(hào),${#變量};
- 截取字符串:可以在變量后使用:截取,${變量:x:y};
- 替換字符串中子字符串:可以在變量后使用/符號(hào),${變量/子字符串/替換的字符串};
- 刪除字符串中的子字符串:實(shí)際上可以通過替換子字符串的方法實(shí)現(xiàn);
- 字符串大小寫替換:可以使用^^轉(zhuǎn)換成大寫,使用,,轉(zhuǎn)換成小寫;
下面,我們可以從下面的例子更直觀的了解這些操作。
a="Hello World"
echo "${#a}" #獲取字符串長度
echo "${a:6:3}" #從下標(biāo)6開始截取3字符
echo "${a/ll/hh}" #將字符串中的ll替換為hh
echo "${a/or/}" #刪除子字符串or
echo "${a^^}" #全部轉(zhuǎn)化成大寫
echo "${a,,}" #全部轉(zhuǎn)化成小寫
字符串操作
數(shù)字運(yùn)算
在上面的變量章節(jié),我們學(xué)習(xí)到了可以使用$[運(yùn)算表達(dá)式]形式,使數(shù)字變量進(jìn)行運(yùn)算。這一章節(jié),我們將會(huì)詳細(xì)了解數(shù)字運(yùn)算。實(shí)際上Shell可以使用命令和運(yùn)算表達(dá)式的方式進(jìn)行數(shù)字運(yùn)算,它們可以支持+ - * / %等算術(shù)運(yùn)算。
命令方式主要有l(wèi)et declare expr等命令,下面我們一一通過例子來學(xué)習(xí)他們的使用。
通過let命令進(jìn)行數(shù)字運(yùn)算,let命名后直接跟上運(yùn)算表達(dá)式即可。
#!/bin/sh
a="4"
b="2"
let c1=${a}+$
let c2=${a}-$
let c3=${a}*$
let c4=${a}/$
let c5=${a}%$
echo "a + b =" ${c1}
echo "a - b =" ${c2}
echo "a * b =" ${c3}
echo "a / b =" ${c4}
echo "a % b =" ${c5}
let命令
通過expr命令進(jìn)行數(shù)字運(yùn)算,可以查看下面的示例代碼,但是需要注意兩點(diǎn):
- 運(yùn)算符和兩邊的變量需要使用空格隔開;
- 需要注意需要將*轉(zhuǎn)義為*。
#!/bin/sh
a=4
b=2
c1=$(expr ${a} + $)
echo "a + b =" ${c1}
c2=$(expr ${a} - $)
echo "a - b =" ${c2}
c3=$(expr ${a} * $)
echo "a * b =" ${c3}
c4=$(expr ${a} / $)
echo "a / b =" ${c4}
c5=$(expr ${a} % $)
echo "a % b =" ${c5}
expr
declare命令也可以進(jìn)行數(shù)字運(yùn)算,它的參數(shù)選項(xiàng)中有一個(gè)-i選項(xiàng),它可以將變量聲明為整數(shù)型,因此,我們也可以通過declare實(shí)現(xiàn)數(shù)字的運(yùn)算。
#!/bin/sh
a="4"
b="2"
declare -i c1=${a}+$
declare -i c2=${a}-$
declare -i c3=${a}*$
declare -i c4=${a}/$
declare -i c5=${a}%$
echo "a + b =" ${c1}
echo "a - b =" ${c2}
echo "a * b =" ${c3}
echo "a / b =" ${c4}
echo "a % b =" ${c5}
declare命令
通過運(yùn)算表達(dá)式實(shí)現(xiàn)數(shù)字運(yùn)算的方式,主要有$((運(yùn)算表達(dá)式))和$[運(yùn)算表達(dá)式],我們依次來看看他們的使用方法。
#!/bin/sh
a=4
b=2
c1=$((${a}+$))
c2=$((${a}-$))
c3=$((${a}*$))
c4=$((${a}/$))
c5=$((${a}%$))
echo "a + b =" ${c1}
echo "a - b =" ${c2}
echo "a * b =" ${c3}
echo "a / b =" ${c4}
echo "a % b =" ${c5}
表達(dá)式方式1
#!/bin/sh
a=4
b=2
c1=$[${a}+$]
c2=$[${a}-$]
c3=$[${a}*$]
c4=$[${a}/$]
c5=$[${a}%$]
echo "a + b =" ${c1}
echo "a - b =" ${c2}
echo "a * b =" ${c3}
echo "a / b =" ${c4}
echo "a % b =" ${c5}
表達(dá)式方式2
除了這些運(yùn)算之外,shell也支持自增和自減運(yùn)算,這里以let命令為例:
#!/bin/sh
c1=2
c2=2
c3=2
let c1++
let c2--
let c3+=1
echo "c1 =" ${c1}
echo "c2 =" ${c2}
echo "c3 =" ${c3}
自增和自減
上面的這些運(yùn)算方法都有各自的要求,在使用的時(shí)候我們一定要清楚它們的使用方法。另外,在默認(rèn)情況下shell是不支持小數(shù)運(yùn)算,大家可以發(fā)現(xiàn)上面的運(yùn)算都是整數(shù)運(yùn)算,怎么進(jìn)行小數(shù)運(yùn)算呢?
我們可以借助Linux平臺(tái)下的bc計(jì)算器進(jìn)行小數(shù)運(yùn)算。
#!/bin/sh
a=1.411
b=1.332
c1=`echo "$a+$b"|bc`
c2=`echo "$a-$b"|bc`
c3=`echo "$a*$b"|bc`
c4=`echo "scale=3;$a/$b"|bc` #scale用來指定小數(shù)的位數(shù)
echo $c1
echo $c2
echo $c3
echo $c4
小數(shù)運(yùn)算
數(shù)組
Shell可以定義數(shù)組用來存放多個(gè)數(shù)據(jù),格式如下,數(shù)組中的各個(gè)元素需要使用空格隔開,數(shù)組在定義時(shí)可以不用指定數(shù)組的大小。
array=(value1 value2 value3 ...)
在訪問數(shù)組時(shí),可以使用中括號(hào)和下標(biāo)([下標(biāo)])訪問各個(gè)元素,它的下標(biāo)也是從0開始的。
#!/bin/sh
a=(hello world code)
echo ${a[0]}
echo ${a[1]}
echo ${a[2]}
數(shù)組訪問
除了用下標(biāo)訪問單個(gè)元素之外,是否有其他方法獲取所有元素呢?我們可以使用*和@符號(hào)獲取數(shù)組的所有元素。這兩個(gè)符號(hào)是不是很熟悉?我們?cè)谧址兞坎僮髡鹿?jié)用到過這兩個(gè)符號(hào)。
#!/bin/sh
a=(hello world code)
echo ${a[*]}
echo ${a[@]}
獲取數(shù)組所有元素
同樣的,與獲取字符變量長度類似,我們也可以使用#符號(hào)來獲取數(shù)組的長度。
#!/bin/sh
a=(hello world code)
echo ${#a[*]}
獲取數(shù)組長度
關(guān)系運(yùn)算
關(guān)系運(yùn)算也就是比較運(yùn)算,因?yàn)樵趕hell里都是字符串類型,我們?cè)趺幢容^數(shù)字的大小呢?shell中專門提供了一些專門用來關(guān)系運(yùn)算的運(yùn)算符。如下:
- -eq:可以判斷兩個(gè)數(shù)是否相等,相等則為ture,格式為[ $a -eq $b ];
- -ne:可以判斷兩個(gè)數(shù)是否不相等,不相等則為true,格式為[ $a -ne $b ];
- -gt:可以左邊的數(shù)是否大于右邊的,如果是則為true,格式為[ $a -gt $b ];
- -lt:可以判斷左邊的數(shù)是否小于右邊的,如果是則為true,格式為[ $a -lt $b ];
- -ge:可以判斷左邊的數(shù)是否大于等于右邊的,如果是則為true,格式為[ $a -ge $b ];
- -le:可以判斷左邊的數(shù)是否小于等于右邊的,如果是則為true,格式為[ $a -le $b ]。
這里要注意變量和中括號(hào)兩邊是有空格隔開,運(yùn)算符和變量之間也有空格隔開,具體我們可以通過一個(gè)例子來進(jìn)一步了解它們的使用。
#!/bin/sh
a=1
b=2
if [ $a -eq $b ];then
echo "yes"
else
echo "no"
fi
if [ $a -ne $b ];then
echo "yes"
else
echo "no"
fi
if [ $a -gt $b ];then
echo "yes"
else
echo "no"
fi
if [ $a -lt $b ];then
echo "yes"
else
echo "no"
fi
這里用到了判斷語句if...else,詳細(xì)內(nèi)容可以在條件語句章節(jié)再深入了解。
關(guān)系運(yùn)算
上面的是數(shù)值關(guān)系運(yùn)算,當(dāng)然,對(duì)于字符串同樣也有類似的元素符。
=:判斷兩個(gè)字符串是否相等,相等則為真,[ $a = $b ] ;
!= 判斷兩個(gè)字符串是否不相等,不相則為真,[ $a != $b ];
-z 判斷字符串長度是否為0,如果是則為真,[ -z $a ];
-n 判斷字符串長度是否不為0,如果是則為真,[ -n "$a" ];
$ 判斷字符串是否為空,如果不為空則為真,[ $a ];
#!/bin/sh
a="hello"
b="hello"
c="world"
d=""
echo "a = b ?"
if [ $a = $b ];then
echo "yes"
else
echo "no"
fi
echo "a != b ?"
if [ $a != $b ];then
echo "yes"
else
echo "no"
fi
echo "a != c ?"
if [ $a != $c ];then
echo "yes"
else
echo "no"
fi
echo "len(c) = 0 ?"
if [ -z $c ];then
echo "yes"
else
echo "no"
fi
echo "len(d) != 0 ?"
if [ -n "$d" ];then
echo "yes"
else
echo "no"
fi
echo "len(a) = 0 ?"
if [ $a ];then
echo "yes"
else
echo "no"
fi
字符串
邏輯運(yùn)算
除了我們上面介紹的算術(shù)運(yùn)算和關(guān)系運(yùn)算,Shell還有邏輯運(yùn)算。邏輯運(yùn)算主要有邏輯與和邏輯或運(yùn)算。
- 邏輯與運(yùn)算使用&&表示,運(yùn)算符兩邊都為真則結(jié)果為真;
- 邏輯或運(yùn)算使用||表示,運(yùn)算符兩邊只要有一個(gè)為真則結(jié)果為真。
我們通過一個(gè)例子來對(duì)邏輯運(yùn)算進(jìn)一步了解。
#!/bin/sh
a=1
b=2
c=1
echo "a = c && a != b ?"
if [[ $a -eq $c && $a -ne $b ]];then
echo "yes"
else
echo "no"
fi
echo "a = b || a = c ?"
if [[ $a -eq $b || $a -eq $c ]];then
echo "yes"
else
echo "no"
fi
邏輯運(yùn)算
條件語句
與其他語言一樣,shell腳本編程也可以進(jìn)行流程控制,比如,條件語句,循環(huán)語句等,這一章節(jié)我們學(xué)習(xí)條件語句。
條件語句中主要通過if else then elif fi等關(guān)鍵字組成,主要可以組成下面幾種情況:
- 單分支
- 雙分支
- 多分支:多個(gè)條件,多個(gè)執(zhí)行分支
單分支這種情況,結(jié)構(gòu)比較簡單,一個(gè)條件一個(gè)執(zhí)行分支。
a=1
if [ $a == 1 ];then
echo "a = 1"
fi
單分支
雙分支的情況,比單分支多一個(gè)執(zhí)行分治。
a=1
if [ $a == 2 ];then
echo "a = 1"
else
echo "a != 1"
fi
雙分支
多分支結(jié)構(gòu)比較適合多種條件,多個(gè)執(zhí)行分支的情況。
a=2
if [ $a == 1 ];then
echo "a = 1"
elif [ $a == 2 ];then
echo "a = 2"
else
echo $a
fi
多分支
對(duì)于if的分支語句大家要注意格式問題,在[]里的條件表達(dá)式一定要和兩邊中括號(hào)符號(hào)用空格隔開。
此外,還有一種多分支語句case語句,格式為:
case $變量 in
"value1")
執(zhí)行語句1
;;
"value2")
執(zhí)行語句2
;;
*)
執(zhí)行其他語句
;;
esac
我們看一個(gè)case語句的示例:
#!/bin/sh
read -p "please in put a number:" num
case $num in
"1")
echo "Start 1th flow"
;;
"2")
echo "Start 2th flow"
;;
*)
echo "Do nothing"
esac
case語句
上面的這些只是一些簡單的語句結(jié)構(gòu),大家只要掌握了這幾種分支語句的用法,就可以組成更加復(fù)雜的分支語句,比如,多個(gè)判斷條件,多個(gè)分支嵌套等。
循環(huán)語句
用于流程控制的另一種方式是循環(huán)語句,Shell中常見有for while until select這四種循環(huán)語句。下面我們依次來了解這四種循環(huán)方式。
for循環(huán)for(())和for...in這兩種形式,我們可以根據(jù)自己的需要進(jìn)行選擇。
先來看看for(())這種循環(huán)格式:
for((ex1;exp2;exp3))
do
循環(huán)體
done
這里我們可以結(jié)合的數(shù)組的知識(shí)來舉個(gè)循環(huán)的栗子。
a=("hello" "world" "hello" "shell")
for((i=0;i<4;i++))
do
echo ${a[i]}
done
for循環(huán)
我們通過定義一個(gè)遞增變量i,依次訪問數(shù)組各個(gè)元素。有沒有更簡單的變量方法呢?我們?cè)倏聪旅嬉粋€(gè)例子。
a=("hello" "world" "hello" "shell")
for v in ${a[*]}
do
echo $v
done
for...in
上面的例子用的是第二種for...in的循環(huán)格式,其格式如下,它可以方便的遍歷一個(gè)列表或數(shù)組,而不需再定義遞增/遞減變量。
for var in list
do
循環(huán)體
done
接下來我們看while循環(huán),while循環(huán)的格式如下,
while [ 條件表達(dá)式 ]
do
循環(huán)體
done
再看一個(gè)例子:
a=("hello" "world" "hello" "shell")
i=0
while [ $i -lt 4 ]
do
echo ${a[i]}
let i++
done
while
while循環(huán)需要注意條件表達(dá)的寫法,相信看了上面的關(guān)于條件語句的同學(xué)已經(jīng)很清楚了。
在shell中有一個(gè)與while循環(huán)恰好相反的循環(huán)until循環(huán);在while循環(huán)中條件表達(dá)式成立就會(huì)進(jìn)入循環(huán)體,而在until循環(huán)中條件表達(dá)式不成立才會(huì)進(jìn)入循環(huán),until循環(huán)的格式如下:
until [ 條件表達(dá)式 ]
do
循環(huán)體
done
我們將上面while循環(huán)例子的條件表達(dá)式稍加改動(dòng)。
a=("hello" "world" "hello" "shell")
i=0
until [ $i -ge 4 ]
do
echo ${a[i]}
let i++
done
until
對(duì)于until循環(huán)語句來說,一般沒有上面的幾種循環(huán)語句較為常用。
最后,還有一種較為特殊的循環(huán)select,我們先看一下它的格式:
select var in list
do
statements
done
為什么說它是一種特殊的循環(huán)?我們看下面這個(gè)例子:
a=("hello" "world" "hello" "shell")
i=0
select v in ${a[*]}
do
echo $v
done
select
從這里例子上,我們可以發(fā)現(xiàn)在每行打印前面都有一個(gè)序號(hào),我們還可以選擇其中一個(gè)序號(hào),會(huì)輸出對(duì)應(yīng)需要的結(jié)果。它是shell中特有的一種結(jié)構(gòu),通常和case...in語句一起使用,通過根據(jù)選擇的序號(hào)不同,可以選擇執(zhí)行case...in里不同的動(dòng)作。
a=("公司A" "公司B" "公司C" "公司D")
select v in ${a[*]}
do
case $v in
"公司A")
echo "恭喜您,你選擇了公司A !"
break
;;
"公司B")
echo "恭喜您,你選擇了公司B !"
break
;;
"公司C")
echo "恭喜您,你選擇了公司C !"
break
;;
"公司D")
echo "恭喜您,你選擇了公司D !"
break
;;
*)
echo "您沒有選擇任何一個(gè)公司,請(qǐng)重新選擇!"
esac
done
select in 和 case in
函數(shù)
在一個(gè)復(fù)雜的功能的腳本程序中,會(huì)有很多重復(fù)或相似的功能,為了避免大量的重復(fù)代碼,這個(gè)時(shí)候函數(shù)的作用體現(xiàn)出來了。一般的我們會(huì)將一些相似的或重復(fù)的操作抽象成一個(gè)函數(shù),并根據(jù)參數(shù)的不同返回相應(yīng)的結(jié)果。這樣程序?qū)⒏吣K化,邏輯也更加清楚,便于開發(fā)和維護(hù)。
當(dāng)然,在shell中也可以使用函數(shù)。其格式如下:
function name() {
# 函數(shù)體
return value
}
這里function是用來定義函數(shù)的關(guān)鍵字,name是需要我們自定義的函數(shù)名,return value是函數(shù)的返回值?,F(xiàn)在我們來定義一個(gè)函數(shù):
function test1() {
echo "this is a function"
return 0
}
該怎么調(diào)用函數(shù)呢?直接寫函數(shù)名即可,我們看一個(gè)完整版程序:
function test1() {
echo "this is a function"
return 0
}
test1 #調(diào)用函數(shù)
函數(shù)1
上面函數(shù)沒有帶參數(shù)的,那如果有參數(shù)怎么辦呢?我們繼續(xù)看例子:
function test2() {
echo "parameter1 : $1"
echo "parameter2 : $2"
return 3
}
test2 1 2 #調(diào)用函數(shù)
echo $? #獲取函數(shù)返回值
函數(shù)2
實(shí)際上,函數(shù)中是不要定義形參的,在調(diào)用時(shí)在函數(shù)后面加上實(shí)參就可以了。而函數(shù)體中可以通過$加參數(shù)編號(hào)訪問參數(shù),比如,第一個(gè)參數(shù)$1,到第十個(gè)參數(shù)以上就需要加上{}符號(hào),比如${10},而函數(shù)返回值需要在調(diào)用該函數(shù)后通過$?獲得。
文件包含
有的時(shí)候某個(gè)功能可能被多個(gè)腳本使用,這時(shí)就需要在將這個(gè)功能放到一個(gè)公共的文件中,需要這個(gè)功能的腳本直接包含這個(gè)公共的文件即可,這就是文件的包含,同樣的Shell也是支持文件包含的。
在Shell中可以使用.或source加上文件名來包含文件。直接來看例子:
先建一個(gè)文件test_one.sh:
#test_one.sh
var1=1
再建一個(gè)文件test_two.sh:
#test_two.sh
var2=2
下面我們?cè)诮ㄒ粋€(gè)文件包含test_one.sh和test_two.sh這兩個(gè)文件。
. ./test_one.sh
source ./test_two.sh
echo "file one var1=${var1}"
echo "file two var2=${var2}"
文件包含
這里需要注意.和./test_one.sh文件之間是有一個(gè)空格。
最后
至此,我們已經(jīng)學(xué)會(huì)了shell編程的一些基本知識(shí)。文中使用的都是一些簡單的例子,在實(shí)際的shell腳本中往往都是比較復(fù)雜的邏輯。不過,再復(fù)雜的代碼也是有這些簡單的結(jié)構(gòu)組成。因此,大家一定要有一個(gè)扎實(shí)基礎(chǔ)和掌握一個(gè)完整的shell知識(shí)體系。