Shell腳本編程總結(jié)及速查手冊(轉(zhuǎn))

Shell是一種編程語言, 它像其它編程語言如: C, Java, Python等一樣也有變量/函數(shù)/運算符/if語句/循環(huán)控制/… 但在開始之前, 我想先理清Shell語言與Shell之間的關(guān)系.

Shell與Shell語言

上面說了Shell是一種編程語言但你可能也聽說過: sh/bash/csh/zsh/…它們也叫Shell, 實際上這里所說的Shell是一種應(yīng)用程序, 它負責(zé)解釋執(zhí)行你編寫的Shell腳本, Mac默認就自帶了sh/bash/csh/zsh/tcsh/ksh, 你可以這樣查看cat /etc/shells

不同的shell的用法基本相同, 但有些shell提供了一些新特性, 比如我現(xiàn)在在用的就是zsh, 更多zsh的內(nèi)容可以去看這篇文章

第一個Shell腳本

#! /bin/sh

echo "hello shell!"

依國際慣例這里以在終端里打印一句hello shell!開始, 第一行的#!是一個約定標記, 它告訴腳本這段腳本需要什么解釋器來執(zhí)行. 第二行的echo命令則負責(zé)向屏幕上輸出一句話.

如何運行

運行shell程序有3種方法:

chmod +x使文件具有可執(zhí)行權(quán)限, 直接運行

直接調(diào)用解釋器, 將腳本文件作為參數(shù)傳入 (比如bash hi.sh)

使用source(也可用 . 代替)執(zhí)行文件

通常情況下, 最方便的方式就是方式1, 通過方式1執(zhí)行你需要在腳本第一行寫好這段腳本由哪個解釋器來解釋, 而通過方式2來執(zhí)行則沒有這個限制, 寫了也沒用.

除此之外方式1與方式2執(zhí)行命令就沒有區(qū)別了, 但方式3執(zhí)行的方式與前兩種都不同:

使用source執(zhí)行shell腳本時, 不會創(chuàng)建子進程, 而是在父進程中直接執(zhí)行!

這里不作更多解釋, 感興趣的同學(xué)可以去參考Linux Shell編程從入門到精通這本書的第一章的相關(guān)部分.

變量

和其它語言一樣Shell中也有變量, 而且更簡單, 但有一些比較特殊的地方.

Shell中的變量只有字符串這一種類型

Shell中變量名與變量值沒有長度限制

Shell的變量也允許比較操作和整數(shù)操作, 只要變量中的字符串為數(shù)字

定義變量

variable_name=ghui

需要注意: = 兩邊不能加空格, 當(dāng)賦值語句包含空格時請加引號(單引號/雙引號均可)比如:

variable_name="ghui's blog"

Shell中的變量可以分為兩種類型:

局部變量 (定義變量時在前面加local修飾符)

全局變量 (定義變量時不加任何修飾符)

與其它語言一樣局部變量的可見范圍是代碼塊或函數(shù)內(nèi), 全局變量在全局范圍內(nèi)可見.看個簡單的例子:

#! /bin/sh

num=111 #全局變量

func1()

{

?local num=222 #局部變量

?echo $num

}

echo "before---$num"

func1

echo "after---$num"

輸出:

before---111

222

after---111

使用變量

使用一個定義過的變量, 只要在變量名前面加$即可, 如:

name=ghui

echo $name

echo ${name} #{} 為了幫助解釋器識別變量邊界, 非必須

在使用變量時還有一個地方需要注意, 請看下面的例子:

#! /bin/sh

str='abc'

echo "1 print $str"

echo '2 print $str'

輸出:

1 print abc

2 print $str

即:

被雙引號括起來的變量會發(fā)生變量替換, 單引號不會

注釋

Shell中注釋使用#, 而且它不支持多行注釋.

常用的字符串操作

字符串拼接

name="shell"

sayHi="hello, "$name" !"

sayHi2="hello, ${name} !"

echo $sayHi $sayHi2

注意: 上面說的單雙引號引起的變量替換問題

獲得字符串長度

string="abcd"

echo ${#string} #輸出:4

截取字符串

str="hello shell"

echo ${str:2} ?#輸出: llo shell

echo ${string:1:3} #輸出:ell

更多關(guān)于字符串的操作可以看這個

if/else流程控制

基本語法結(jié)構(gòu):

if condition

then

do something

elif condition

then

do something

elif condition

then

do something

else

do something

fi

其中, elif語句和else語句非必須的.看個例子:

#! /bin/sh

a=1

if [ $1=$a ]

then

echo "you input 1"

elif [ $1=2 ]

then

echo "you input 2"

else

#do nothing

echo " you input $1"

fi

很簡單, 不過這里有兩個地方需要注意, 如果某個條件下的執(zhí)行體為空, 則你就不能寫這個條件 即下面這樣會報錯:

if condition

then

#do nothing

elif condition

then

# do nothing

#or

else

#do nothing

另外, [ ] 兩邊一定要加空格, 下面這樣都會報錯:

if [$a=$b]

#or

if [ $a=$b]

#or

if [$a=$b ]

只有這樣if [ $a=$b ]才是對的.

注意: 實際上這里的[]是test命令的一種形式, [是系統(tǒng)的一個內(nèi)置命令,存在路徑是/bin/[,它是調(diào)用test命令的標識, 右中括號是關(guān)閉條件判斷的標識, 因此下面的兩個測試語句是等效的:

if test "2>3"

then

...

fi

if [ "2>3" ]

then

fi

除[]之外, shell語言中還有幾種其它括號, 比如: 單小括號/雙小括號/雙中括號/… , 不同的括號有不同的用法, 更多關(guān)于shell中, 括號的用法可以看看這個

switch流程控制

當(dāng)條件較多時, 可以選擇使用switch語句, shell中的switch語句的寫法和其它語言還是有些不同的, 基本結(jié)構(gòu)如下:

case expression in

pattern1)

do something... ;;

pattern2)

do something... ;;

pattern2)

do something... ;;

...

esac

看個例子:

#! /bin/sh

input=$1

case $input in

? ? ? ?1 | 0)

? ? ? ?str="一or零";;

? ? ? ?2)

? ? ? ?str="二";;

? ? ? ?3)

? ? ? ?str="三";;

? ? ? ?*)

? ? ? ?str=$input;;

esac

echo "---$str"

這個例子會根據(jù)你執(zhí)行此腳本時傳入的參數(shù)不同在屏幕上輸出不同的值, 其中第一個case 1 | 0代表邏輯或.

NOTE:

;;相當(dāng)于其它語言中的break

每個pattern之后記得加)

最后記得加esac (即反的case)

for循環(huán)

基本結(jié)構(gòu):

for name [in list]

do

...

done

其中,[]括起來的 in list, 為可選部分, 如果省略in list則默認為in "$@", 即你執(zhí)行此命令時傳入的參數(shù)列表.

看個例子:

for file in *.txt

do

open $file

done

遍歷當(dāng)前目錄下的所有txt文件, 并依次打開.

while循環(huán)

基本結(jié)構(gòu):

while condition

do

do something...

done

看個例子:

#! /bin/sh

i=0

while ((i<5));

do

((i++))

echo "i=$i"

done

輸出:

i=1

i=2

i=3

i=4

i=5

NOTE: 你可能需要去了解一下(())的用法

until循環(huán)

基本結(jié)構(gòu)

until condition

do

do something...

done

看個例子:

#! /bin/sh

i=5

until ((i==0))

do

((i--))

echo "i=$i"

done

輸出:

i=4

i=3

i=2

i=1

i=0

跳出循環(huán)

shell中也支持break跳出循環(huán), continue跳出本次循環(huán).用法與C, Java中相同

函數(shù)

要定義一個函數(shù), 可以使用下面兩種形式:

function funcname()

{

do something

}

或者

funcname ()

{

do something

}

看個例子

#! /bin/sh

# ad.sh 計算sum

add()

{

let "sum=$1+$2"

return $sum

}

add $1 $2

echo "sum=$?"

輸入

ad 1 2

輸出

sum=3

其中, $?在shell中保存的是上一條命令的返回值

NOTE:

函數(shù)必須先定義后使用

如果在函數(shù)中使用exit會退出腳本, 如果想退回到原本函數(shù)調(diào)用的地方, 則可使用return

向腳本傳遞參數(shù)

先shell腳本傳遞參數(shù), 非常簡單, 只需要在你執(zhí)行命令的后面跟上即可, 看個例子:

#! /bin/sh

# test.sh

echo "$# parameters";

echo "$@";

echo "$0"

echo "$1"

輸入:

test.sh 11 22

輸出:

2 parameters

11 22

test.sh

11

后記

之所以要寫這篇博客, 有以下幾個原因:

想總結(jié)一下shell編程中的關(guān)鍵知識點, 方便日后查看.

想通過shell優(yōu)化一下我的hexo寫作及博客管理流程, 目前相關(guān)腳本已完成, 待我下一篇博客分享給大家, 如果你也是在用Hexo寫博客, 相信對你會很有用, 盡請期待! 已經(jīng)發(fā)布

可以看的出這里總結(jié)的都是最關(guān)鍵的知識點, 還有很多這里并沒有說. 是因為我覺得剛開始學(xué)習(xí)一個東西沒必要太計較一些細節(jié)/瑣碎的東西, 掌握好大致知識框架, 然后在大家編寫具體的腳本時, 遇到具體問題, 再去google尋找即可.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市档痪,隨后出現(xiàn)的幾起案子绑榴,更是在濱河造成了極大的恐慌,老刑警劉巖蹂午,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件栏豺,死亡現(xiàn)場離奇詭異,居然都是意外死亡豆胸,警方通過查閱死者的電腦和手機奥洼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來晚胡,“玉大人灵奖,你說我怎么就攤上這事」琅蹋” “怎么了桑寨?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長忿檩。 經(jīng)常有香客問我尉尾,道長,這世上最難降的妖魔是什么燥透? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任沙咏,我火速辦了婚禮辨图,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘肢藐。我一直安慰自己故河,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布吆豹。 她就那樣靜靜地躺著鱼的,像睡著了一般。 火紅的嫁衣襯著肌膚如雪痘煤。 梳的紋絲不亂的頭發(fā)上凑阶,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天,我揣著相機與錄音衷快,去河邊找鬼宙橱。 笑死,一個胖子當(dāng)著我的面吹牛蘸拔,可吹牛的內(nèi)容都是我干的师郑。 我是一名探鬼主播,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼调窍,長吁一口氣:“原來是場噩夢啊……” “哼宝冕!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起邓萨,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤猬仁,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后先誉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體湿刽,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年褐耳,在試婚紗的時候發(fā)現(xiàn)自己被綠了诈闺。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,785評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡铃芦,死狀恐怖雅镊,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情刃滓,我是刑警寧澤仁烹,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布,位于F島的核電站咧虎,受9級特大地震影響卓缰,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一征唬、第九天 我趴在偏房一處隱蔽的房頂上張望捌显。 院中可真熱鬧,春花似錦总寒、人聲如沸扶歪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽善镰。三九已至,卻和暖如春年枕,著一層夾襖步出監(jiān)牢的瞬間炫欺,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工画切, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人囱怕。 一個月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓霍弹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親娃弓。 傳聞我的和親對象是個殘疾皇子典格,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容

  • 個人學(xué)習(xí)批處理的初衷來源于實際工作;在某個迭代版本有個BS(安卓手游模擬器)大需求台丛,從而在測試過程中就重復(fù)涉及到...
    Luckykailiu閱讀 4,718評論 0 11
  • 1.創(chuàng)建文件夾 !/bin/sh mkdir -m 777 "%%1" 2.創(chuàng)建文件 !/bin/sh touch...
    BigJeffWang閱讀 10,055評論 3 53
  • 建立一個腳本 Linux中有好多中不同的shell耍缴,但是通常我們使用bash (bourne again shel...
    某人在閱讀 2,008評論 0 0
  • 目 錄 |惟有蘭花香正好 上一章 |我來到,你的世界 文 |唐媽 我將水龍頭開到最大挽霉,白花花的自來水沖在黃瓜上防嗡,...
    唐媽閱讀 3,701評論 69 85
  • 一路上葵花的心一直懸著,怕城志見到自己會不高興侠坎。好不容易到了車站蚁趁,四下搜尋沒有看到城志的身影,葵花懸著的心...
    妖尾醬閱讀 246評論 0 0