zoukankan      html  css  js  c++  java
  • shell函数(调用、返回值,返回值获取)

    Shell函数返回值,常用的两种方式:returnecho

    1) return 语句
    shell函数的返回值,可以和其他语言的返回值一样,通过return语句返回。
    示例1:

    [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 函数返回值只能是整形数值,一般是用来表示函数执行成功与否的,0表示成功,其他值表示失败。因而用函数返回值来返回函数执行结果是不合适的。如果要硬生生地return某个计算结果,比如一个字符串,往往会得到错误提示:“numeric
    argument required”。
    如果一定要让函数返回一个或多个值,可以定义全局变量,函数将计算结果赋给全局变量,然后脚本中其他地方通过访问全局变量,就可以获得那个函数“返回”的一个或多个执行结果了。

     

    重新修改下示例2:

    [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。

    A、如何调用shell函数(执行函数):函数名 参数

    B、获取shell函数结果:$?

    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)用$?来接收函数的执行状态,但是$?要紧跟在函数调用处的后面。

  • 相关阅读:
    socket选项设置
    shell 备忘录
    VIM中cscope和tags数据库的添加
    MFC程序设计中的BeginPaint/EndPaint和GetDC/ReleaseDC的使用
    shell 命令行参数解析
    do{...}while(0)用法总结
    0长度数组的使用
    在线帮助文档
    GCC编译器帮助文档
    几款优秀的Linux基准测试工具
  • 原文地址:https://www.cnblogs.com/duanxz/p/4661767.html
Copyright © 2011-2022 走看看