1. 程式人生 > >馬哥學習---李洋個人筆記-----函數

馬哥學習---李洋個人筆記-----函數

顏色 執行 階乘 打印 情況 部分 The HA 寫作

函數
函數function是由若幹條shell命令組成的語句塊,實現代碼重用和模塊化編程 它與shell程序形式上是相似的,不同的是它不是一個單獨的進程,不能獨立運行,而是shell程序 的一部分
函數和shell程序比較相似,區別在於: ? Shell程序在子Shell中運行 ? 而Shell函數在當前Shell中運行。因此在當前Shell中,函數可以對shell中變量進行修改
函數的命名方式,通常不使用已定義的別名,或命令來當函數的名字,因為函數的優先級非常高。比如使用ls當函數名,那麽當函數運行後,再敲ls不會顯示文件了,而是取決於函數當中的函數體。函數命名方式(最通用的):系統自帶函數默認帶下劃線。
函數名 (){
函數體
}
的形式來命名,兩種括號之間沒有空格,如果函數體中包含有當前shell已被定義的變量,最好在定義的變量前加上local 避免幹擾報錯,例子

函數(){ ----------------------------定義一個實現打印 name=李洋的函數

name=李洋

echo “函數:$name”

} ------------------------- 定義完成

name= 黃樂穎 -------------------------- 又定義name=黃樂穎

ecnho $name ---------------------------打印變量$name

李洋 由此可以看出,函數的判定高於變量。

為了避免這種沖突,我們在函數體中加入 local就可以避免這種情況了。

函數(){

local name=李洋 ---------------------- 前面加上了local

echo “函數:$name”

}

name= 黃樂穎

黃樂穎 ------------------------- 不在影響變量了

函數的定義和使用:
– 可在交互式環境下定義函數,即命令行下定義函數,但是這兩樣的函數只在本次登錄的的shell中生效,不會永久生效,當前用戶退出則函數丟失。

– 可將函數放在腳本文件中作為它的一部分
而放入腳本中的函數,想在腳本內部使用的話,必須先定義,再調用。

– 可放在只包含函數的單獨文件中

調用:函數只有被調用才會執行 調用格式:
函數名 (函數名出現的地方,會被自動替換為函數中的代碼 )像命令一樣使用,也可以自定義一些參數選項。比如寫一個腳本:
#1 /bin/bash

redyel(){

if [ "$1" = "-r" ];then echo -e "\033[1;41m \033[1;43m \033[0m";return;fi

echo -e "\033[1;43m \033[1;41m \033[0m"

}

redyel

redyel –r

加入一個判斷項目,就可以像執行命令一樣來使用函數了。 比如執行完這個腳本後,我們在命令行單獨輸入

redyel 就會看到×××和紅色的方塊。

而想調用多個函數的文件,假設腳本名字為yanse.sh,那麽在命令行輸入點+空格+yanse.sh 就可以看到由黃紅,紅黃組成的顏色小方塊了。

函數的生命周期:被調用時創建,返回時終止

函數有兩種返回值:
1 函數的執行結果返回值:
(1) 使用echo等命令進行輸出
在函數尾部加入 echo 數字(假設為3) ,然後執行完函數後,在命令行輸入
echo 函數名 ,那麽顯示的值就為3.例如

add (){ c=$[3+3]; echo $c; } 打印出來$c的值為6,但是在執行函數中不會顯示,而是把這個值賦給函數本身,

add 查看這個函數的值

6 值為6.

(2) 函數體中調用命令的輸出結果

add (){ c=$[3+3]; echo $c; return 10;}

這時候add的值依然為6,但是echo $?的值已經被 return 改為了10.

2 函數的退出狀態碼:
(1) 默認取決於函數中執行的最後一條命令的退出狀態碼

(2) 自定義退出狀態碼,其格式為:

return 從函數中返回,用最後狀態命令決定返回值

return 0 無錯誤返回。

return 1-255 有錯誤返回

在函數中任意位置插入return就相當於結束這個函數。

使用函數文件
1 文件名可任意選取,但最好與相關任務有某種聯系。例如: functions.main
2 可以將經常使用的函數存入函數文件,然後將函數文件載入shell
3 一旦函數文件載入shell,就可以在命令行或腳本中調用函數。可以使用 set命令查看所有定義的函數,其輸出列表包括已經載入shell的所有函 數
4 若要改動函數,首先用unset命令從shell中刪除函數。避免出現沖突。改動完畢後,再重新載入此文件。
5 一般函數只會在當前shell中生效,若想全局都生效,可以使用export命令來實現。 # export –f 函數名 可以將指定函數變為全局函數(一般不這麽用,函數通常都是引用的方式,定義了函數後,在其他腳本中使用直接 函數名 即可 )

函數遞歸
用來實現函數自身調用自身的方式。舉例:

vim hanshu.sh

!/bin/bash

fact() {

if [ $1 -eq 0 -o $1 -eq 1 ]; then

echo 1

else

echo $[$1*$(fact $[$1-1])] fi

}

fact $1

這個例子中,是實現階乘的方式。(一個正整數的階乘,是所有小於及等於該數的正整數的積,並且有0的階乘為1,自然數n的 階乘寫作n!),n!=1×2×3×...×n
在上例中,假設n的值為10,由函數生命周期可知,起始於$1值為10的時候,終止於$1值為1的時候。因為值不為1的時候,因為條件不滿足,所以不停的被調用自身,當值為1的時候,開始輸出並返回值。函數的生命周期:被調用時創建,返回時終止.
$[$1*$(fact $[$1-1])] 當中:

中括號部分,即$[$1-1]是取值$1-1後的值。

小括號部分fact $[$1-1]是函數調用時,每一次去判斷條件時所用的值。

大括號部分[$1*$(fact $[$1-1])]則是用$1的值,乘以自身-1後的值。

設$1為10,那麽這裏的運算式可以看做 10*9
使用命令 bash –x +函數名來查看詳細執行過程

  • fact 10-------------------------------------------當值為10的時候
  • ‘[‘ 10 -eq 0 -o 10 -eq 1 ‘]‘--------------------10不滿足條件,執行else部分
    ++ fact 9---------------------------------減1後值為9,再次調用函數去執行if判斷部分
    ++ ‘[‘ 9 -eq 0 -o 9 -eq 1 ‘]‘----------------------依然不滿足條件
    +++ fact 8-------------------------------減1後值為8,再次調用函數去執行if判斷部分
    +++ ‘[‘ 8 -eq 0 -o 8 -eq 1 ‘]‘--------------------依然不滿足條件
    ++++ fact 7-----------------------------減1後值為7,再次調用函數去執行if判斷部分
    ++++ ‘[‘ 7 -eq 0 -o 7 -eq 1 ‘]‘------------------依然不滿足條件
    +++++ fact 6---------------------------減1後值為6,再次調用函數去執行if判斷部分
    +++++ ‘[‘ 6 -eq 0 -o 6 -eq 1 ‘]‘----------------依然不滿足條件
    ++++++ fact 5-------------------------減1後值為5,再次調用函數去執行if判斷部分
    ++++++ ‘[‘ 5 -eq 0 -o 5 -eq 1 ‘]‘---------------依然不滿足條件
    +++++++ fact 4-----------------------減1後值為4,再次調用函數去執行if判斷部分
    +++++++ ‘[‘ 4 -eq 0 -o 4 -eq 1 ‘]‘--------------依然不滿足條件
    ++++++++ fact 3---------------------減1後值為3,再次調用函數去執行if判斷部分
    ++++++++ ‘[‘ 3 -eq 0 -o 3 -eq 1 ‘]‘------------依然不滿足條件
    +++++++++ fact 2--------------------減1後值為2,再次調用函數去執行if判斷部分
    +++++++++ ‘[‘ 2 -eq 0 -o 2 -eq 1 ‘]‘-----------依然不滿足條件
    ++++++++++ fact 1------------------減1後值為1,再次調用函數去執行if判斷部分
    ++++++++++ ‘[‘ 1 -eq 0 -o 1 -eq 1 ‘]‘---------滿足條件,開始輸出
    ++++++++++ echo 1----------------值為1時,所返回的值。這個1是then返回的。
    +++++++++ echo 2------------------值為2時,所返回的值。21的值
    ++++++++ echo 6--------------------值為3時,所返回的值。3
    21的值
    +++++++ echo 24--------------------值為4時,所返回的值。4
    321的值
    ++++++ echo 120--------------------值為5時,所返回的值。5….1的值
    +++++ echo 720----------------------值為6時,所返回的值。6…..
    1的值
    ++++ echo 5040----------------------值為7時,所返回的值。7……. 1的值
    +++ echo 40320----------------------值為8時,所返回的值。8…..
    1的值
    ++ echo 362880----------------------值為9時,所返回的值。9….. *1的值
  • echo 3628800----------------------值為10時,所返回的值。10….. *1的值
    3628800--------------------輸出取值為10時候,函數的值。是由else當中的echo來輸出的。

    由上面分析可以看出,每一次判斷後,都會把原本要產生的值存起來,接著去調用函數來判斷,然後當條件滿足時,反過來(從10開始判斷,從1開始計算)計算產生的值。最終用echo來輸出最終值。

    也就是說,當$1的值為1的時候,函數滿足了輸出條件。開始反向計算之前,條件不滿足,所欠的(保存的)值一一計算出來並返回。
    也可以理解為,當$1的值為1時候,函數計算出來值。有了1的值,就可以去計算2的值,然後有了2的值,就可以去計算3的……直到最後計算完。

馬哥學習---李洋個人筆記-----函數