背景
如今,不會li程式設計客棧nux的程式設計師都不意思說自己是程式設計師,而不會shell程式設計就不能說自己會linux。通過shell程式設計,寫一些工具批處理的時候,經常需要自定義函式。更複雜點的情況下,可能有需要返回乙個值。
由於在shell的世界中,並不像其他程式語言,它不支援我們所熟悉的方法返回。本文一起總結一下如何優雅的解決返回值問題?
測試程式
我們一般通過$?來獲取上乙個語句的輸出。看一下下面得測試語句:
新建testreturn指令碼
returnstring()
returnstring $1
result=$?
echo "result=$result"
現在我們有乙個testreturn的指令碼,裡面有乙個returnstring的方法,我們希望它能夠直接返回我們輸入的引數。
當我們分別以hello,500,12作為輸入引數時,他的執行和輸出情況是一樣的麼?
./testreturn hello
./testreturn 500
./testreturn 12
在心中試著猜一下可能的情況,現在我們來揭曉答案:
程式輸出情況
在執行hello的時候,並沒有輸出hello,而是報了乙個return只接受數字型別的錯誤
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn hello
./testreturn: line 23: return: hello: numeric argument required
result=255
在執行500的時候,頁沒有輸出500,而是輸出了244
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn 500
result=244
執行12的時候,終於正確了,返回12
**en-mac-pro-2:**enwu.github.io **en$ ./test程式設計客棧return 12
result=12
異常分析
現在我們分析一下returnstring這個方法,為什麼會有這麼多種輸出情況呢?
首先他的寫法顯然是不嚴謹的,但也不是完全錯誤,比如輸入12他就正確返回了。
return本身是shell裡面的buildin函式,筆者總結了下,他有以下幾個特徵:
全域性變數
如果我們就是要返回乙個字串,怎麼辦呢?可以通過定義全域性變數來進行賦值,類似於靜態變數/成員變數的寫法,我們讓他的作用域穿透整個上下文。
result=""
returnstring()
returnstring $1
echo "result=$result"
再看一下輸出,得到了我們需要的結果:
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn hello
result=he程式設計客棧llo
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn 500
result=500
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn 12
result=12
但是這樣寫,會汙染全域性變數,並且result這個變數很容易在內部和外部都被修改,導致內部修改失效。
eval
除了return,還有其他一些buildin的關鍵字,比如eval,local。
預設在當前指令碼定義的變數都是全域性變數,在方法中則可以通過locwww.cppcns.comal來定義區域性變數,這樣可以避免全域性變數汙染.
同時結合eval賦值語句,來實現變數的修改
returnstring()
returnstring $1 result
echo "result=$result"
同樣我們也得到了希望的結果
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn hello
result=hello
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn 500
result=500
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn 12
result=12
echo
最後在介紹一種方法,通過echo輸出,結合command substitution。
這個command substitution也沒有找到比較合適的翻譯,姑且按字面意思翻譯命令替換。
如果你的方法內部只有一處echo輸出,那麼也可以利用她來進行值得返回,不過這個就有點侷限性,一定要確保方法內只有一次輸出,否則就會出現賦值內容過多。
returnstring()
# 或者 result=`returnstring $1`
result=$(returnstring $1)
echo "result=$result"
同樣可以得到預期結果
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn hello
result=hello
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn 500
result=500
**en-mac-pro-2:**enwu.github.io **en$ ./testreturn 12
result=12
越界問題
現在我們已經有幾種辦法可以返回字串了,那麼return返回數字有時候正確,有時候又不正確是為什麼呢?
我們知道return原本就是用於返回執行狀態的,比如0,1.那麼我們在返回500的時候,實際上是資料溢位了。
根據測試,我們推斷shell的內建return承接返回值用的是乙個位元組的大小,也就是8位,最多可以輸出無符號0-255的整形,範圍之外的資料全部溢位顯示。因此在使用return的時候,務必留意數值大小。
小結通過shell命令可以很方便的寫出一些小指令碼,但是如果遇到邏輯複雜,建議通過其他更合適的預覽來實現,比如python,golang之類。
總結本文標題: shell中關於處理方法返回值問題詳解
本文位址: /os/linux/214790.html
關於Shell中函式的返回值問題
bin sh sum sum 1 2 c sum 1 2 echo echo c 執行命令 bashtest 11 1 執行結果是 12 sum 1 2的結果 10 echo 的結果,因為return的值為10 12 echo c的結果,值為12,所以c並不會被附上return的值,echo c時呼...
關於處理JDBC返回值問題
此時可以使用resultset類的get方法,如獲取字串型別則getstring 獲取int型則getint 括號之中的引數為要查詢欄位在資料庫中的列名。resultset resultset stat.executequery sql if resultset.next 除此之外,也可以採用自定義...
shell 返回值一
今天看同事寫的指令碼,發現其中用乙個函式為變數賦值,然後發現那個函式的return值並非是我所期望的值,於是查詢了一些資料,發現自己之前對return的理解大大的錯誤了。return命令會使得乙個函式返回return命令會返回乙個單一的數字引數,而這個數字引數 0 255 在呼叫這個函式的指令碼中是...