同步發表:http://blog.hacktons.cn/2017/12/13/shell-func-return/linux
經過shell編程,寫一些工具批處理的時候,常常須要自定義函數。更復雜點的狀況下,可能有須要返回一個值。
因爲在shell的世界中,並不像其餘編程語言,它不支持咱們所熟悉的方法返回。本文一塊兒總結一下如何優雅的解決返回值問題?git
咱們通常經過$?
來獲取上一個語句的輸出。看一下下面得測試語句:github
新建testReturn
腳本shell
returnString(){ return $1 } returnString $1 result=$? echo "result=$result"
如今咱們有一個testReturn的腳本,裏面有一個returnString的方法,咱們但願它可以直接返回咱們輸入的參數。
當咱們分別以hello
,500
,12
做爲輸入參數時,他的執行和輸出狀況是同樣的麼?編程
./testReturn hello ./testReturn 500 ./testReturn 12
在心中試着猜一下可能的狀況,如今咱們來揭曉答案:bash
在執行hello的時候,並無輸出hello,而是報了一個return只接受數字類型的錯誤編程語言
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello ./testReturn: line 23: return: hello: numeric argument required result=255
在執行500的時候,頁沒有輸出500,而是輸出了244函數
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500 result=244
執行12的時候,終於正確了,返回12工具
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12 result=12
如今咱們分析一下returnString這個方法,爲何會有這麼多種輸出狀況呢?
首先他的寫法顯然是不嚴謹的,但也不是徹底錯誤,好比輸入12他就正確返回了。測試
return
自己是shell裏面的buildin函數,筆者總結了下,他有如下幾個特徵:
若是咱們就是要返回一個字符串,怎麼辦呢?能夠經過定義全局變量來進行賦值,相似於靜態變量/成員變量的寫法,咱們讓他的做用域穿透整個上下文。
result="" returnString(){ result=$1 } returnString $1 echo "result=$result"
再看一下輸出,獲得了咱們須要的結果:
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello result=hello aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500 result=500 aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12 result=12
可是這樣寫,會污染全局變量,而且result這個變量很容易在內部和外部都被修改,致使內部修改失效。
除了return
,還有其餘一些buildin的關鍵字,好比eval
,local
。
默認在當前腳本定義的變量都是全局變量,在方法中則能夠經過local來定義局部變量,這樣能夠避免全局變量污染.
同時結合eval賦值語句,來實現變量的修改
returnString(){ local __result=$2 eval $__result=$1 } returnString $1 result echo "result=$result"
一樣咱們也獲得了但願的結果
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello result=hello aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500 result=500 aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12 result=12
最後在介紹一種方法,經過echo
輸出,結合command substitution
。
這個command substitution
也沒有找到比較合適的翻譯,姑且按字面意思翻譯命令替換
。
若是你的方法內部只有一處echo輸出,那麼也能夠利用她來進行值得返回,不過這個就有點侷限性,必定要確保方法內只有一次輸出,不然就會出現賦值內容過多。
returnString(){ local __result=$1 echo $__result } # 或者 result=`returnString $1` result=$(returnString $1) echo "result=$result"
一樣能夠獲得預期結果
aven-mac-pro-2:avenwu.github.io aven$ ./testReturn hello result=hello aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 500 result=500 aven-mac-pro-2:avenwu.github.io aven$ ./testReturn 12 result=12
如今咱們已經有幾種辦法能夠返回字符串了,那麼return返回數字有時候正確,有時候又不正確是爲何呢?
咱們知道return本來就是用於返回執行狀態的,好比0,1.那麼咱們在返回500的時候,其實是數據溢出了。
根據測試,咱們推斷shell的內置return承接返回值用的是一個字節的大小,也就是8位,最多能夠輸出無符號0-255的整形,範圍以外的數據所有溢出顯示。所以在使用return的時候,務必留意數值大小。
經過shell命令能夠很方便的寫出一些小腳本,可是若是遇到邏輯複雜,建議經過其餘更合適的預覽來實現,好比Python,Golang之類。