Shell中關於處理方法返回值問題詳解

2022-09-26 15:03:19 字數 3164 閱讀 7010

背景

如今,不會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 在呼叫這個函式的指令碼中是...