shell腳本編程進(jìn)階:函數(shù)

一、函數(shù)介紹

函數(shù)function是由若干條shell命令組成的語句塊,實(shí)現(xiàn)代碼重用和模塊化編程篙议;
它與shell程序形式上是相似的,不同的是它不是一個(gè)單獨(dú)的進(jìn)程,不能獨(dú)立運(yùn)行鬼贱,而是shell程序的一部分移怯;
函數(shù)和shell程序比較相似,區(qū)別在于:
(1)Shell程序在子Shell中運(yùn)行这难;
(2)Shell函數(shù)在當(dāng)前Shell中運(yùn)行舟误;因此在當(dāng)前Shell中,函數(shù)可以對shell中變量進(jìn)行修改姻乓;

例如:
腳本1:clean.sh:rm -rf /app/x/*
腳本2:f1.sh:
#!/bin/bash
echo f1.sh
/app/bin/clean.sh(bash調(diào)用)

二嵌溢、定義函數(shù)

定義函數(shù)=定義別名;
建議不要用與系統(tǒng)cmd相同的函數(shù)名蹋岩;
企業(yè)規(guī)范函數(shù)命名:f_name 或者 func_name赖草;

declear -f f_name  查看某個(gè)函數(shù)
declear -f   查看所有函數(shù)
declear -x   查看所有環(huán)境變量
unset f_name  取消(刪除)函數(shù)
函數(shù)(兩部分組成):函數(shù)名和函數(shù)體;
help function

語法一:
function f_name {
       ...函數(shù)體...
}

語法二:
function f_name(){
      ...函數(shù)體...
}

語法三:(建議)
f_name(){
      ...函數(shù)體...
}

注意:
function f_name(){ cmd; }  
不換行——必須加 星澳;和 “空格”(中括號里)疚顷;

例如:
function clean () { echo clean1;echo clean2; }
clean
unset clean

三、函數(shù)的定義和使用

1.函數(shù)——聲明禁偎、定義腿堤;函數(shù)生效——調(diào)用;(先定義如暖,后調(diào)用)
2.函數(shù)只有被調(diào)用才會(huì)執(zhí)行笆檀;
3.調(diào)用方法:給定函數(shù)名;
4.函數(shù)名出現(xiàn)的地方盒至,會(huì)被自動(dòng)替換為函數(shù)代碼酗洒;
5.函數(shù)的生命周期:被調(diào)用時(shí)創(chuàng)建,返回時(shí)終止枷遂;
(1)交互式環(huán)境下定義函數(shù)樱衷;(類似cat)
f_name {
>...
>... 
>}
(2)將函數(shù)放在腳本文件中作為它的一部分;
在腳本前面先定義函數(shù)酒唉;然后在調(diào)用函數(shù)矩桂;只適用于自己使用;
#!/bin/bash
f_name {
    echo f_name
}
f_name
(3)放在只包含函數(shù)的單獨(dú)文件中痪伦;(可以被其他文件調(diào)用)
系統(tǒng)定義的函數(shù)都放在這個(gè)文件:cat /etc/init.d/functions侄榴;
grep '^.*().*' /etc/init.d/functions|wc -l  統(tǒng)計(jì)函數(shù)庫中函數(shù)個(gè)數(shù)
自己可以定義:vim functions    (定義函數(shù)的文件,可以不寫shebang機(jī)制)
f_name1 {
    echo f_name
}
f_name2 {
    echo f_name
}

例如:testfuc.sh
#!/bin/bash
. /app/bin/functions    (調(diào)用函數(shù)庫)
echo cmd1    (腳本自己的程序)
f_name1    (調(diào)用的函數(shù))
f_name2    (調(diào)用的函數(shù))

四网沾、函數(shù)返回值(兩種)

1.函數(shù)的執(zhí)行結(jié)果返回值
(1)使用echo等命令進(jìn)行輸出癞蚕;
(2)函數(shù)體中調(diào)用命令的輸出結(jié)果;
2.函數(shù)的退出狀態(tài)碼
(1)默認(rèn)取決于函數(shù)中執(zhí)行的最后一條命令的退出狀態(tài)碼辉哥;
(2)自定義退出狀態(tài)碼桦山,其格式為:
return  從函數(shù)中返回食茎,用最后狀態(tài)命令決定返回值
return 0  無錯(cuò)誤返回
return 1-255  有錯(cuò)誤返回
例1
vim functions
func1 {
      echo 100
}
func2 {
      echo func2-cmd1
      return(100或者exit)
      echo func2-cmd2
}

. functions  使系統(tǒng)里有緩存(如果更改functions文件膘婶,需要重新使其重新生效乍赫,就執(zhí)行此操作)
func1:100  使系統(tǒng)里有緩存
let i=`func1`+200  `func1`可被其他命令調(diào)用(即:當(dāng)做別名使用)
echo $i:300
func2:(1)return:退出函數(shù)暂吉;(2)exit:退出腳本;

例2
vim testfunc.sh
. /app/bin/functions(例1中的functions庫)
func2  (例1中的func2)
echo continue

testfunc.sh(運(yùn)行)
(1)return:退出函數(shù)寇窑;func2-cmd1  continue
(2)exit:退出腳本鸦概;func2-cmd1

例3
vim testfunc.sh
. /app/bin/functions(例1中的functions庫)
func2  (例1中的func2)
echo $?    return 顯示:0(真);return 100 顯示:100(假)甩骏;
echo continue

五窗市、使用函數(shù)文件

1.可以將經(jīng)常使用的函數(shù)存入函數(shù)文件,然后將函數(shù)文件載入shell饮笛;
2.文件名可任意選取咨察,但最好與相關(guān)任務(wù)有某種聯(lián)系;例如:functions.main福青;
3.一旦函數(shù)文件載入shell摄狱,就可以在命令行或腳本中調(diào)用函數(shù);
set  查看所有定義的函數(shù)无午,其輸出列表包括已經(jīng)載入shell的所有函數(shù)媒役;
4.若要改動(dòng)函數(shù),首先用unset命令從shell中刪除函數(shù)宪迟;改動(dòng)完畢后酣衷,再重新載入此文件;
國際象棋(思路)
red(){ echo -e '\033[41m \033[0m'; };red
red;red;red;red
yellow(){ echo -e '\033[43m \033[0m'; };yellow
yellow;yellow;yellow;yellow
red;red;red;red;yellow;yellow;yellow;yellow

六次泽、函數(shù)參數(shù)

cat /etc/init.d/sshd
腳本調(diào)用參數(shù)
(空格)/etc/init.d/sshd status
(空格)/etc/init.d/sshd restart

1.函數(shù)可以接受參數(shù)

(1)傳遞參數(shù)給函數(shù)
調(diào)用函數(shù)時(shí)穿仪,在函數(shù)名后面以空白分隔給定參數(shù)列表即可;
例如:“testfunc arg1 arg2 ...”意荤;
(2)在函數(shù)體中啊片,
使用 $1, $2, ...調(diào)用這些參數(shù);還可以使用 $@, $*, $# 等特殊變量玖像;
例
(1)vim functions
func {
      echo 1st is $1
      echo 2st is $2
      echo all args are $*
      echo the arg numbers is $#
      echo funcname is $0
}
max {
      [ $1 -gt $2 ] && echo max is $1 || echo max is $2
}

(2)testfunc1.sh
. /app/bin/functions
func a b c
echo continue

(3)testfunc2.sh
. /app/bin/functions
max 10 20
echo continue
(4). functions  更改functions文件钠龙,需要重新使其重新生效

2.函數(shù)變量

變量作用域
(1)環(huán)境變量:當(dāng)前shell和子shell有效;
(2)本地變量:只在當(dāng)前shell進(jìn)程有效御铃,為執(zhí)行腳本會(huì)啟動(dòng)專用子shell進(jìn)程;作用范圍是當(dāng)前shell腳本程序文件沈矿,包括腳本中的函數(shù)上真;
(3)局部變量:函數(shù)的生命周期;函數(shù)結(jié)束時(shí)變量被自動(dòng)銷毀羹膳;
(4)注意:如果函數(shù)中有局部變量睡互,如果其名稱同本地變量,使用局部變量
(5)在函數(shù)中定義局部變量的方法
local NAME=VALUE
使用腳本中定義的變量(最好加上括號)
(1)vim functions
func () {
      (var=fuc)函數(shù)是否定義變量
      echo $var
      echo func-cmd1
      return 100
      echo func-cmd2
}
(2)vim testfunc.sh
. /app/bin/functions
var=testfunc
func
echo continue

(3). functions  更改functions文件,需要重新使其重新生效
(4)testfunc.sh
函數(shù)未定義變量:testfunc func-cmd1 continue
函數(shù)定義變量:func func-cmd1 continue
變量名相同時(shí)就珠,函數(shù)里的變量可以更改腳本中的變量寇壳;所以盡量避免變量名稱相同(防止混亂);
local NAME=VALUE  此變量只在函數(shù)中有效
為了區(qū)分妻怎,可以統(tǒng)一變量名:local local_NAME=VALUE
步驟1:vim functions
func () {
      local var=fuc
      echo $var
      echo func-cmd1
      return 100
      echo func-cmd2
}

步驟2:vim testfunc.sh
. /app/bin/functions
var=testfunc
echo var=$var
func
echo var=$var
echo continue

步驟3:. functions  更改functions文件壳炎,需要重新使其重新生效

步驟4:bash testfunc.sh

七、函數(shù)遞歸

函數(shù)遞歸:函數(shù)直接或間接調(diào)用自身逼侦;注意遞歸層數(shù)匿辩;

n!=1×2×3×...×n
n!=(n-1)!×n
n!=(n-2)!×(n-1)×n
vim fact.sh
#!/bin/bash
fact () {
    if [ $1 -eq 0 -o $1 -eq 1 ]; then
    echo 1
    else
    echo $[$1*$(fact $[$1-1])]
fi
}
fact $1(調(diào)用自己+參數(shù))

執(zhí)行操作
fact.sh 10
fact.sh -1  死循環(huán);直至資源耗盡榛丢;
killall fact.sh  
pstree -p  保留原來狀態(tài)(進(jìn)程)铲球,循環(huán)下一個(gè)狀態(tài)(進(jìn)程);
ps auxf|less
linux遞歸函數(shù)調(diào)用晰赞,嵌套深度無限制稼病;編寫腳本時(shí),要注意合理利用函數(shù)調(diào)用掖鱼;
Paste_Image.png

fork炸彈

1.fork炸彈
一種惡意程序然走,它的內(nèi)部是一個(gè)不斷在fork進(jìn)程的無限循環(huán),實(shí)質(zhì)是一個(gè)簡單的遞歸程序锨用;
由于程序是遞歸的丰刊,如果沒有任何限制,這會(huì)導(dǎo)致這個(gè)簡單的程序迅速耗盡系統(tǒng)里面的所有資源增拥;
2.函數(shù)實(shí)現(xiàn)
:() { :|:& };:
bomb() { bomb | bomb & }; bomb
3.腳本實(shí)現(xiàn)
cat bomb.sh
#!/bin/bash
./$0|./$0&

八啄巧、匿名函數(shù)和環(huán)境函數(shù)

匿名函數(shù):{ cmd1;cmd2 }
環(huán)境函數(shù)
(1)定義函數(shù);
(2)declare -fx 或 export -f  聲明環(huán)境函數(shù)掌栅;
(3)調(diào)用秩仆;
讓子進(jìn)程繼承父進(jìn)程的函數(shù);
Paste_Image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末猾封,一起剝皮案震驚了整個(gè)濱河市澄耍,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌晌缘,老刑警劉巖齐莲,帶你破解...
    沈念sama閱讀 211,290評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異磷箕,居然都是意外死亡选酗,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,107評論 2 385
  • 文/潘曉璐 我一進(jìn)店門岳枷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來芒填,“玉大人呜叫,你說我怎么就攤上這事〉钏ィ” “怎么了朱庆?”我有些...
    開封第一講書人閱讀 156,872評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長闷祥。 經(jīng)常有香客問我娱颊,道長,這世上最難降的妖魔是什么蜀踏? 我笑而不...
    開封第一講書人閱讀 56,415評論 1 283
  • 正文 為了忘掉前任维蒙,我火速辦了婚禮,結(jié)果婚禮上果覆,老公的妹妹穿的比我還像新娘颅痊。我一直安慰自己,他們只是感情好局待,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,453評論 6 385
  • 文/花漫 我一把揭開白布斑响。 她就那樣靜靜地躺著,像睡著了一般钳榨。 火紅的嫁衣襯著肌膚如雪舰罚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,784評論 1 290
  • 那天薛耻,我揣著相機(jī)與錄音营罢,去河邊找鬼。 笑死饼齿,一個(gè)胖子當(dāng)著我的面吹牛饲漾,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播缕溉,決...
    沈念sama閱讀 38,927評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼考传,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了证鸥?” 一聲冷哼從身側(cè)響起僚楞,我...
    開封第一講書人閱讀 37,691評論 0 266
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎枉层,沒想到半個(gè)月后泉褐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,137評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鸟蜡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,472評論 2 326
  • 正文 我和宋清朗相戀三年膜赃,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片矩欠。...
    茶點(diǎn)故事閱讀 38,622評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡财剖,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出癌淮,到底是詐尸還是另有隱情躺坟,我是刑警寧澤,帶...
    沈念sama閱讀 34,289評論 4 329
  • 正文 年R本政府宣布乳蓄,位于F島的核電站咪橙,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏虚倒。R本人自食惡果不足惜美侦,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,887評論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望魂奥。 院中可真熱鬧菠剩,春花似錦、人聲如沸耻煤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,741評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽哈蝇。三九已至棺妓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間炮赦,已是汗流浹背怜跑。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留吠勘,地道東北人性芬。 一個(gè)月前我還...
    沈念sama閱讀 46,316評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像看幼,于是被迫代替她去往敵國和親批旺。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,490評論 2 348

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

  • 1诵姜、c語言的函數(shù)有以下特點(diǎn): (1)才源程序由函數(shù)組成汽煮,一個(gè)主函數(shù)main()+若干其他函數(shù) C程序中的函數(shù)類似文...
    滕王閣序閱讀 1,335評論 0 6
  • 原文鏈接:https://github.com/EasyKotlin 值就是函數(shù),函數(shù)就是值棚唆。所有函數(shù)都消費(fèi)函數(shù)暇赤,...
    JackChen1024閱讀 5,957評論 1 17
  • 前言 把《C++ Primer》[https://book.douban.com/subject/25708312...
    尤汐Yogy閱讀 9,511評論 1 51
  • 現(xiàn)在在大橋下面吃燒烤,因?yàn)楦苫罾哿讼瑁钡酵?點(diǎn)才回家鞋囊。不想做飯了,所以來大橋下面吃燒烤瞎惫。 這家店的生意一如既往的好...
    南受朝北閱讀 180評論 0 0
  • 8月中旬溜腐,終于開始計(jì)劃已久的馬爾代夫之行译株,朋友曾勸說先去去別的海島再到馬爾代夫,因見過了馬代的海其他大多數(shù)的海島都...
    方政博閱讀 828評論 1 10