Shell編程中函數部分的相關講解

Bash與”真正的”編程語言一樣,Bash也有函數,雖然在某些實現方面稍有限制。一個函數就是一個子程序,用於實現一系列操作的代碼塊,它是完成特定任務的”黑盒子”。當存在重複代碼的時候,或者當一個任務只需要輕微修改就被重複使用的時候,就需要考慮使用函數了。

函數定義

定義函數有兩種方法:

function foo() {
    #1
}

foo() {
    #2 這種方法和c語言更加貼近,兼容性也更好。
}

需要注意的是函數的定義需要在使用之前。

函數參數

在調用函數的時候可以給函數傳遞參數。

如:

foo "bar"

如何在函數中使用這些參數呢,Bash中有特定的符號來表示各個參數。

  • $0就是腳本文件自身的名字,$1是第一個參數, $2是第二個參數,$3是第三個參數,以此類推。需要注意的是9以上的參數爲了避免Bash解析錯誤,需要加上大括號或者雙引號(使用${10},防止其被解析爲${1}0的形式)。
  • $* 表示這個程式的所有參數。
  • $#表示這個程式的參數個數。

關於函數中變量的聲明:如果變量用local來聲明, 那麼它就只能夠在該變量被聲明的代碼塊中可見。這個代碼塊就是局部”範圍”。在一個函數中, 一個局部變量只有在函數代碼塊中才有意義。

函數的返回值

Bash函數中的return關鍵字會返回這個函數的退出狀態碼(shell中不區分變量的類型。但是shell會區分這個變量是整形還是字符串,其關鍵就是這個變量的值中是否只有數字。如果是整形則可以使用算數運算符對其進行計算。)。調用者可以通過讀取$?來獲取函數的退出狀態碼變量($?變量保存了一個命令,一個函數,或者是腳本本身的退出狀態碼)。我們可以通過設置全局變量或者使用命令替換。

下面這個簡單的例子使用全局變量的方法進行了返回值的傳遞。

function foo() {
    r="sometext"
}

foo
echo "$r"

這種做法雖然很簡單方便,但是過多的定義全局變量將會導致這個程序的維護成本急劇增加。

更好的方法是在函數中使用local變量,然後再結合命令替換的方式來把想傳遞的值傳給調用者:

function foo() {
    local r="sometext"
    echo "$r"
}

result=$(foo)  #等價於result=`foo`
echo "$result"

在這個例子中結果被輸出到stdout中,這樣的話調用者就可以通過命令替換來獲取返回值了。

還有一種方法可以進行值的返回,調用者可以將變量的名字傳給函數,然後函數將返回值存儲到這個名字的變量之中,這樣調用者就可以直接通過訪問這個變量來獲取返回值了。

function myfunc()
{
    local  r=$1
    local  myresult='some text'
    eval $r="'$myresult'"
}

myfunc result
echo $result

被一對雙引號(” “)括起來的變量替換是不會被阻止的。所以雙引號被稱爲部分引用,有時候又被稱爲”弱引用”。但是如果使用單引號的話(’ ‘), 那麼變量替換就會被禁止了,變量名只會被解釋成字面的意思,不會發生變量替換。所以單引號被稱爲全引用,有時候也被稱爲”強引用”。所以在以上的例子中要使用some text作爲值的時候就不能使用”some text”,空格會引起腳本執行錯誤,只能使用’some text’。

在上面的例子中eval會讓shell先對$r="'$myresult'"就行一次掃描和替換,變成result='some text'。然後在正式運行函數的時候就會把’some text’賦值給result變量,這樣調用者在來訪問result變量就可以取得函數的返回值了。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章