Shell函數返回值精講
在 C++、Java、C#、Python 等大部分編程語言中,返回值是指函數被調用之后,執行函數體中的代碼所得到的結果,這個結果就通過 return 語句返回。
但是 shell 中的返回值表示的是函數的退出狀態:返回值為 0 表示函數執行成功了,返回值為非 0 表示函數執行失?。ǔ鲥e)了。if、while、for 等語句都是根據函數的退出狀態來判斷條件是否成立。
Shell 函數的返回值只能是一個介于 0~255 之間的整數,其中只有 0 表示成功,其它值都表示失敗。
函數執行失敗時,可以根據返回值(退出狀態)來判斷具體出現了什么錯誤,比如一個打開文件的函數,我們可以指定 1 表示文件不存在,2 表示文件沒有讀取權限,3 表示文件類型不對。
如果函數體中沒有 return 語句,那么使用默認的退出狀態,也就是最后一條命令的退出狀態。如果這就是你想要的,那么更加嚴謹的寫法為:
return $?
$?
是一個特殊變量,用來獲取上一個命令的退出狀態,或者上一個函數的返回值,請猛擊《Shell $?》了解更多。
如何得到函數的處理結果?
有人可能會疑惑,既然 return 表示退出狀態,那么該如何得到函數的處理結果呢?比如,我定義了一個函數,計算從 m 加到 n 的和,最終得到的結果該如何返回呢?
這個問題有兩種解決方案:
一種是借助全局變量,將得到的結果賦值給全局變量;
一種是在函數內部使用 echo、printf 命令將結果輸出,在函數外部使用
$()
或者``
捕獲結果。
下面我們具體來定義一個函數 getsum,計算從 m 加到 n 的和,并使用以上兩種解決方案。
【實例1】將函數處理結果賦值給一個全局變量。
#!/bin/bash sum=0 #全局變量 function getsum(){ for((i=$1; i<=$2; i++)); do ((sum+=i)) #改變全局變量 done return $? #返回上一條命令的退出狀態 } read m read n if getsum $m $n; then echo "The sum is $sum" #輸出全局變量 else echo "Error!" fi
運行結果:
1
100
The sum is 5050
這種方案的弊端是:定義函數的同時還得額外定義一個全局變量,如果我們僅僅知道函數的名字,但是不知道全局變量的名字,那么也是無法獲取結果的。
【實例2】在函數內部使用 echo 輸出結果。
#!/bin/bash function getsum(){ local sum=0 #局部變量 for((i=$1; i<=$2; i++)); do ((sum+=i)) done echo $sum return $? } read m read n total=$(getsum $m $n) echo "The sum is $total" #也可以省略 total 變量,直接寫成下面的形式 #echo "The sum is "$(getsum $m $n)
運行結果:
1↙
100↙
The sum is 5050
代碼中總共執行了兩次 echo 命令,但是卻只輸出一次,這是因為$()
捕獲了第一個 echo 的輸出結果,它并沒有真正輸出到終端上。除了$()
,你也可以使用``
來捕獲 echo 的輸出結果,請猛擊《Shell變量》了解兩者的區別。
這種方案的弊端是:如果不使用$()
,而是直接調用函數,那么就會將結果直接輸出到終端上,不過這貌似也無所謂,所以我推薦這種方案。
總起來說,雖然C語言、C++、Java 等其它編程語言中的返回值用起來更加方便,但是 Shell 中的返回值有它獨特的用途,所以不要帶著傳統的編程思維來看待 Shell 函數的返回值。
beylze編程學院,一個分享編程知識和seo優化知識的網站。跟著beylze一起學習,每天都有進步。
通俗易懂,深入淺出,一篇文章只講一個知識點。
文章不深奧,不需要鉆研,在公交、在地鐵、在廁所都可以閱讀,隨時隨地漲姿勢。
文章不涉及代碼,不燒腦細胞,人人都可以學習。
當你決定關注beylze(公眾號:beylze),你已然超越了90%的其他從業者!