Shell函數返回值,經常使用的兩種方式:return,echojavascript
1) return 語句
shell函數的返回值,能夠和其餘語言的返回值同樣,經過return語句返回。
示例1:java
[devadmin@swarm1 pos-gateway]$ [devadmin@swarm1 pos-gateway]$ [devadmin@swarm1 pos-gateway]$ #!/bin/sh [devadmin@swarm1 pos-gateway]$ function mytest() > { > echo "arg1 = $1" > if [ $1 = "1" ] ;then > return 'ret1' > else > return 'ret0' > fi > } [devadmin@swarm1 pos-gateway]$ mytest 1 arg1 = 1 -bash: return: ret1: numeric argument required [devadmin@swarm1 pos-gateway]$
「numeric argument required」錯誤:shell
Shell 函數返回值只能是整形數值,通常是用來表示函數執行成功與否的,0表示成功,其餘值表示失敗。於是用函數返回值來返回函數執行結果是不合適的。若是要硬生生地return某個計算結果,好比一個字符串,每每會獲得錯誤提示:「numeric
argument required」。
若是必定要讓函數返回一個或多個值,能夠定義全局變量,函數將計算結果賦給全局變量,而後腳本中其餘地方經過訪問全局變量,就能夠得到那個函數「返回」的一個或多個執行結果了。安全
從新修改下示例2:bash
[devadmin@swarm1 pos-gateway]$ function mytest() { echo "arg1 = $1" ; if [ $1 = "1" ] ;then return 100; else return 200; fi ; } [devadmin@swarm1 pos-gateway]$ [devadmin@swarm1 pos-gateway]$ [devadmin@swarm1 pos-gateway]$ mytest 1 arg1 = 1 [devadmin@swarm1 pos-gateway]$ echo $? 100 [devadmin@swarm1 pos-gateway]$ mytest 2 arg1 = 2 [devadmin@swarm1 pos-gateway]$ echo $? 200 [devadmin@swarm1 pos-gateway]$
示例3:函數
[devadmin@swarm1 pos-gateway]$ if mytest 1; then > echo "mytest 1" > fi arg1 = 1 [devadmin@swarm1 pos-gateway]$
說明:先定義了一個函數mytest,根據它輸入的參數是否爲1來return 100或者return 200。ui
A、如何調用shell函數(執行函數):函數名 參數spa
B、獲取shell函數結果:$?.net
C、另外,能夠直接用函數的返回值用做if的判斷。(示例3)調試
注意:return只能用來返回整數值,且和c的區別是返回爲正確,其餘的值爲錯誤。
2) argv全局變量
這種就相似於C語言中的全局變量(或環境變量)。
示例:
mytest2
args 1
return 0
g_var=1
函數mytest2經過修改全局變量(g_var)的值,來返回結果。
注: 以上兩個方法失效的時候,以上介紹的這兩種方法在通常狀況下都是好使的,但也有例外。
示例:
其中,test.txt 文件中的內容以下:
456:kkk
123:yxb
123:test
結果:
yxb
mytest3 here
1
yxb
g_var=0
mytest4 here
1
g_var=
能夠看到mytest3在return了之後其實沒有直接返回,而是執行了循環體後的語句,同時看到mytest4中也是同樣,同時,在mytest4中,對全局變量的修改也無濟於事,全局變量的值根本就沒有改變。這個是什麼緣由那?
筆者認爲,之因此return語句沒有直接返回,是由於return語句是在管道中執行的,管道實際上是另外一個子進程,而return只是從子進程中返回而已,只是while語句結束了。而函數體以後的語句會繼續執行。
同理,全局變量在子進程中進行了修改,可是子進程的修改沒有辦法反應到父進程中,全局變量只是做爲一個環境變量傳入子進程,子進程修改本身的環境變量,不會影響到父進程。
所以在寫shell函數的時候,用到管道(cmd &後臺進程也同樣)的時候必定要清楚此刻是從什麼地方返回。
3) echo 返回值
其實在shell中,函數的返回值有一個很是安全的返回方式,即經過輸出到標準輸出返回。由於子進程會繼承父進程的標準輸出,所以,子進程的輸出也就直接反應到父進程。
示例4:
#!/bin/sh function test() { echo "arg1 = $1" if [ $1 = "1" ] ;then echo "1" else echo "0" fi } echo echo "test 1" test 1 echo echo "test 0" test 0 echo echo "test 2" test 2
結果:
test 1
arg1 = 1
1
test 0
arg1 = 0
0
test 2
arg1 = 2
0
怎麼?有沒有搞錯,這兩個函數幾乎沒什麼區別,對,它幾乎就是return和echo不同,可是有一點必定要注意,不能向標準輸出一些不是結果的東西(也就是說,不能隨便echo一些不須要的信息),好比調試信息,這些信息能夠重定向到一個文件中解決,特別要注意的是,腳本中用到其它相似grep這樣的命令的時候,必定要記得1>/dev/null 2>&1來空這些輸出信息輸出到空設備,避免這些命令的輸出。
#! /bin/sh function test() { echo "test here" return 100 } DD=`test` #echo excute over echo "return: $?" echo "DD: $DD"
如上shell代碼段,執行結果是
return: 100
DD: test here
若是 把#echo excute over註釋去掉,執行結果是
excute over
return: 0
DD: test here
也就是說:$?是接收上一條函數的執行結果,在例一中,$?接收test函數的執行結果,執行結果其實就是其返回值,就是return 傳出來的數值(return只能是數字,不能是字符串之類的),若是函數中沒有顯式調用return返回出來狀態,那麼系統會使用函數中最後一條shell指令的執行結果做爲返回值,若是函數test()最後一條指令調用其餘函數,如:test1(),那麼test的返回值就是test1的返回值。
DD是做爲一個變量接收函數的標準輸出,好比echo產生出來的信息,不包括報錯之類的信息,如上若是函數test中調用test1,那麼test和test1中的標準輸出都會賦值給變量DD.
注意:DD=`test` , ` `符號不是單引號‘’,而是ESC下面的那個符號,該句話的意思是執行函數test結果賦值給DD,若是是單引號的話這句話是把字符串「test」賦值給變量DD,注意,這句話的執行結果不是賦值是否成功,而是函數的執行狀態
總結:因此,能夠總結一下函數返回值獲取的方法:
1)用變量接收函數返回值,函數用echo等標準輸出將要返回的東西打印出來。
2)用$?來接收函數的執行狀態,可是$?要緊跟在函數調用處的後面。