您的位置:首页 > 运维架构 > Shell

linux的shell函数相关知识

2017-04-26 17:22 288 查看
本文来自整理网络帖子,感谢大家分享。
一、Linux shell 函数参数
在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
带参数的函数示例:
#!/bin/bash
funWithParam(){
echo "The value of the first parameter is $1 !"
echo "The value of the second parameter is $2 !"
echo "The value of the tenth parameter is $10 !"
echo "The value of the tenth parameter is ${10} !"
echo "The value of the eleventh parameter is ${11} !"
echo "The amount of the parameters is $# !"
echo "The string of the parameters is $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73

输出结果:
The value of the first parameter is 1 !
The value of the second parameter is 2 !
The value of the tenth parameter is 10 !
The value of the tenth parameter is 34 !
The value of the eleventh parameter is 73 !
The amount of the parameters is 12 !
The string of the parameters is 1 2 3 4 5 6 7 8 9 34 73 !"

注意,$10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
另外,还有几个特殊字符用来处理参数:

参数处理说明
$#传递到脚本的参数个数
$*以一个单字符串显示所有向脚本传递的参数
$$脚本运行的当前进程ID号
$!后台运行的最后一个进程的ID号
$@与$*相同,但是使用时加引号,并在引号中返回每个参数。
$-显示Shell使用的当前选项,与set命令功能相同。
$?显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
注意:脚本命令输出的参数不能直接传递到函数中,只能在主程序中。

二、Linux shell 函数 返回值

Shell函数返回值,一般有3种方式:return,argv,echo

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

[javascript] view
plain copy

 print?

#!/bin/bash -  

function mytest()  

{  

    echo "arg1 = $1"  

    if [ $1 = "1" ] ;then  

        return 1  

    else  

        return 0  

    fi  

}  

  

echo   

echo "mytest 1"  

mytest 1  

echo $?         # print return result  

  

echo   

echo "mytest 0"  

mytest 0  

echo $?         # print return result  

  

echo   

echo "mytest 2"  

mytest 2  

echo $?         # print return result  

  

  

echo  

echo "mytest 1 = "`mytest 1`  

if  mytest 1 ; then  

    echo "mytest 1"  

fi  

  

echo  

echo "mytest 0 = "`mytest 0`  

if  mytest 0 ; then  

    echo "mytest 0"  

fi  

  

echo  

echo "if fasle" # if 0 is error  

if false; then  

    echo "mytest 0"  

fi  

  

  

echo  

mytest 1  

res=`echo $?`   # get return result  

if [ $res = "1" ]; then  

    echo "mytest 1"  

fi  

  

echo  

mytest 0  

res=`echo $?`   # get return result  

if [ $res = "0" ]; then  

    echo "mytest 0"  

fi  

  

  

  

echo   

echo "end"  

结果:

mytest 1

arg1 = 1

1

mytest 0

arg1 = 0

0

mytest 2

arg1 = 2

0

mytest 1 = arg1 = 1

arg1 = 1

mytest 0 = arg1 = 0

arg1 = 0

mytest 0

if fasle

arg1 = 1

mytest 1

arg1 = 0

mytest 0

end

先定义了一个函数mytest,根据它输入的参数是否为1来return 1或者return 0.
获取函数的返回值通过调用函数,或者最后执行的值获得。
另外,可以直接用函数的返回值用作if的判断。
注意:return只能用来返回整数值,且和c的区别是返回为正确,其他的值为错误。

2) argv全局变量

这种就类似于C语言中的全局变量(或环境变量)。

示例:

[javascript] view
plain copy

 print?

#!/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通过修改全局变量的值,来返回结果。

注: 以上两个方法失效的时候
以上介绍的这两种方法在一般情况下都是好使的,但也有例外。
示例:

[javascript] view
plain copy

 print?

#!/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中,函数的返回值有一个非常安全的返回方式,即通过输出到标准输出返回。因为子进程会继承父进程的标准输出,因此,子进程的输出也就直接反应到父进程。因此不存在上面提到的由于管道导致返回值失效的情况。
在外边只需要获取函数的返回值即可。

示例:

[javascript] view
plain copy

 print?

#!/bin/bash   

 

##############################################  

# Author : IT-Homer  

# Date   : 2012-09-06   

# Blog   : http://blog.csdn.net/sunboy_2050  

##############################################  

  

function mytest5()  

{  

    grep "123" test.txt | awk -F: '{print $2}' | while read line; do  

        if [ $line = "yxb" ]; then  

            echo "0"    # value returned first by this function  

            return 0  

        fi  

    done  

  

    return 1  

}  

  

echo '$? = '"$?"  

result=$(mytest5)  

  

echo "result = $result"  

  

echo  

if [ -z $result ]       # string is null  

then  

    echo "no yxb. result is empyt"  

else  

    echo "have yxb, result is $result"  

fi  

结果:
$? = 0

result = 0

have yxb, result is 0

这个方式虽然好使,但是有一点一定要注意,不能向标准输出一些不是结果的东西,比如调试信息,这些信息可以重定向到一个文件中解决,特别要注意的是,用到比如grep这样的命令的时候,一定要记得1>/dev/null 2>&1来避免这些命令的输出。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: