加入星計(jì)劃,您可以享受以下權(quán)益:

  • 創(chuàng)作內(nèi)容快速變現(xiàn)
  • 行業(yè)影響力擴(kuò)散
  • 作品版權(quán)保護(hù)
  • 300W+ 專業(yè)用戶
  • 1.5W+ 優(yōu)質(zhì)創(chuàng)作者
  • 5000+ 長期合作伙伴
立即加入
  • 正文
  • 推薦器件
  • 相關(guān)推薦
  • 電子產(chǎn)業(yè)圖譜
申請(qǐng)入駐 產(chǎn)業(yè)圖譜

萬字總結(jié) | 完全掌握Shell編程

04/05 11:25
1693
閱讀需 33 分鐘
加入交流群
掃碼加入
獲取工程師必備禮包
參與熱點(diǎn)資訊討論

對(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í)體系。

推薦器件

更多器件
器件型號(hào) 數(shù)量 器件廠商 器件描述 數(shù)據(jù)手冊(cè) ECAD模型 風(fēng)險(xiǎn)等級(jí) 參考價(jià)格 更多信息
DP83867IRRGZR 1 Texas Instruments Industrial temperature, robust gigabit Ethernet PHY transceiver 48-VQFN -40 to 85

ECAD模型

下載ECAD模型
$59.73 查看
LAN8720AI-CP 1 Microchip Technology Inc LAN8720AI-CP

ECAD模型

下載ECAD模型
$1.64 查看
DP83822IRHBR 1 Texas Instruments Low-power, robust 10/100-Mbps Ethernet PHY transceiver with 16-kV ESD 32-VQFN -40 to 85

ECAD模型

下載ECAD模型
$5.64 查看

相關(guān)推薦

電子產(chǎn)業(yè)圖譜