shell函數(調用、返回值,返回值獲取)

Shell函數返回值,經常使用的兩種方式:returnechojavascript

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語言中的全局變量(或環境變量)。

示例:

#!/bin/bash -  
  
g_var=  
function mytest2()  
{  
    echo "mytest2"  
    echo "args $1"  
    g_var=$1  
  
    return 0  
}  
  
mytest2 1  
echo "return $?"  
  
echo  
echo "g_var=$g_var"  

結果:

mytest2
args 1
return 0

g_var=1

函數mytest2經過修改全局變量(g_var)的值,來返回結果。

注: 以上兩個方法失效的時候,以上介紹的這兩種方法在通常狀況下都是好使的,但也有例外。

示例:

#!/bin/bash -  
  
  
function mytest3()  
{  
    grep "123" test.txt | awk -F: '{print $2}' | while read line ;do  
        echo "$line"  
        if [ $line = "yxb" ]; then  
            return 0    # return to pipe only  
        fi  
    done  
  
    echo "mytest3 here "  
    return 1            # return to main process  
}  
  
g_var=  
function mytest4()  
{  
    grep "123" test.txt | awk -F: '{print $2}' | while read line ;do  
        echo "$line"  
        if [ $line = "yxb" ]; then  
            g_var=0  
            echo "g_var=0"  
            return 0    # return to pipe only  
        fi  
    done  
  
    echo "mytest4 here "  
    return 1  
}  
  
mytest3  
echo $?  
  
echo  
mytest4  
echo $?  
  
echo  
echo "g_var=$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)用$?來接收函數的執行狀態,可是$?要緊跟在函數調用處的後面。

相關文章
相關標籤/搜索