欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

shell 脚本编程之函数

程序员文章站 2022-07-10 12:17:16
...

函数定义和调用

function FUNCNAME()
{

}

函数的定义很简单,可以看到和 c 语言的函数定义方式很相似。function 关键字可以省略,省略之后的函数定义跟 c 语言相比就是少了函数返回类型而已。函数调用就更简单了,直接写函数名即可。

#!/bin/bash
FILE=./learn_break.sh
function countLine()
{
    local i=0
    while read line
    do
        let ++i
    done < $FILE
    echo $FILE have $i lines
}
echo call function callLine
countLine

执行结果

call function callLine
./learn_break.sh have 15 lines

函数返回值

函数定义的时候不需要声明返回类型,是函数只能返回整数。可以使用 return 显式地让函数返回某个数,默认返回 0 表示函数正常执行完。函数返回值不一定要放在最后,可以放在前面提前结束函数调用(lua 语言要求返回值必须是函数的最后一条语句)。

#!/bin/bash
FILE=./learn_break.sh
checkFileExist()
{
    if [ -e $FILE ]; then
        return 0
    else
        return 1
    fi
}
echo call function checkFileExist
checkFileExist
if [ $? -eq 0 ]; then
    echo $FILE exist
else
    echo $FILE not exist
fi

执行结果

call function checkFileExist
./learn_break.sh exist

函数参数

前面的例子函数都不能带参数,像检查文件是否存在的脚本,文件名直接写死了,这样如果要检查另一个文件又得修改脚本的内容。因此,函数参数就显得非常重要。shell 不同于 c 语言,不能显式定义形参和实参,而是跟脚本调用一样,使用位置参数。函数体内,使用 $1 到第一个参数的值,依此类推;函数调用时,直接在函数名后面带上参数即可,第一个参数将赋值给函数内的 $1,依此类推。

#!/bin/bash
function checkFileExist()
{
    if [ -e $1 ]; then
        return 0
    else
        return 1
    fi
}
echo call function checkFileExist
checkFileExist $1
if (($?==0)); then
    echo $1 exist
else
    echo $1 no exist
fi

执行结果

[[email protected] ~]$ ./learn_function3.sh noexistfile
call function checkFileExist
noexistfile no exist
[[email protected] ~]$ ./learn_function3.sh learn_break.sh
call function checkFileExist
learn_break.sh exist

执行脚本时把文件名作为第一个参数传进去,此时脚本的 $1 保存的就是文件名;然后调用函数时把脚本的 $1 作为第一个参数传进去,此时函数内的 $1 也是文件名。参数的传递过程是外部传到脚本,再从脚本传给函数。注意脚本中的 $1 和函数内的 $1 是不一样的概念。看看下面的例子

#!/bin/bash
foo()
{
    echo '$1 in function is '$1
}
foo 10
echo '$1 out of function is '$1

执行结果

[ljx@localhost ~]$ ./learn_function4.sh 100
$1 in function is 10
$1 out of function is 100

函数内的 $1 是函数调用时传进去的第一个参数,本例子中传了数字 10;而脚本内的 $1 是脚本执行时传进去的参数,本例子中传了数字 100。脚本本身维护了一个位置参数列表,每个函数也维护了一个位置参数列表,两者之间互不干扰。

重置位置参数

使用 set 关键字可以重置脚本或函数的位置参数,重置后外部调用传进来的位置参数将被覆盖。

#!/bin/bash
function foo()
{
    echo function args list begin set: $1 $2 $3
    set 1 2
    echo function args list after set: $1 $2 $3
}
foo 10 20 30

echo script args list begin set: $1 $2 $3
set 128 256 
echo script args list after set: $1 $2 $3

执行结果

[[email protected] ~]$ ./learn_function5.sh -1 -2 -3
function args list begin set: 10 20 30
function args list after set: 1 2
script args list begin set: -1 -2 -3
script args list after set: 128 256

set 重置的是整个位置参数列表,因此本例子中重置参数后,$3 就变成空了。这里也能再次看出脚本参数与函数参数相互独立。

移动位置参数

使用 shift 关键字可以左移位置参数,shift 后面带一个数字表示左移几位,默认不带的话表示左移一位。左移一位之后,原来 $1 的值就丢失了,$2 的值赋给 $1,$# 减一。

#!/bin/bash
offset=$1
shiftTest()
{
    until ((0)) 
    do
        echo now '$1' is $1,total parameter is $#
        if [[ $# -lt $offset ]]; then
            break
        fi
        shift $offset
    done
}
shift
shiftTest [email protected]

执行结果

[[email protected] ~]$ ./learn_function6.sh 1 10 20 30
now $1 is 10,total parameter is 3
now $1 is 20,total parameter is 2
now $1 is 30,total parameter is 1

在这个脚本中,先把脚本的第一个位置参数保存到 offset 变量中,表示每次向左移几位。然后把脚本剩下的位置参数传给函数,这样函数得到的位置参数就是脚本的位置参数除掉第一个。