Shell系统学习之函数

 系列文章目录

Shell系统学习之什么是Shell

Shell系统学习之创建一个Shell程序

Shell系统学习之向Shell脚本传递参数

Shell系统学习之如何执行Shell程序

Shell系统学习之Shell变量和引用

 Shell系统学习之Shell条件测试,判断语句和运算符

 Shell系统学习之循环结构

 Shell系统学习之函数

Shell系统学习之数组

系统学习Shell之正则表达式

Shell系统学习之文件操作

Shell系统学习之子Shell与进程处理


目录

函数

什么是函数

函数的定义

函数的调用 

函数的返回值 

使用return返回

将返回值输出到标准输出返回

函数和别名 

删除函数

全局变量和局部变量

函数参数 

间接传参

传递数组参数

函数库文件

函数库文件的定义

函数库文件的调用

小结


函数

什么是函数

函数就是将一组相对独立的代码集中起来,形成一个代码块,已完成一个具体的功能。和其他编程语言中的函数是一样的,从本质上讲,函数是一个函数名到某一块代码块的映射。

函数的定义

Shell中函数定义有两种方式,结果是一样的。

#第一种定义方式
function_name ()
{
    statement1
    ...
}

#第二种定义方式
function function_name ()
{
    statement1
    ...
}

 第二种定义方式前面多了一个function关键字。function_name表示函数名,命名规则和变量名一样:可以包含字母,数字,下划线;只能以字母或者下划线开头。用户应该尽量用有意义的英文单词来命名。

在Shell语言中,函数定义必须在函数调用之前,不然会报错

command not found

函数的调用 

调用函数的方式和调用Shell脚本的方式是一样的,调用语法如下:
 

function_name param1 param2 ...

 下面看个简单的例子:

#!/bin/bash
#定义函数
getCurrentTime()
{
    echo "`date`"
}

#调用函数
getCurrentTime

 结果如下:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-2.sh 
Thu 28 Jul 2022 02:17:28 AM PDT

Shell里的函数也和常用的编程语言一样,可以嵌套调用,一个函数里面可以调用另外一个函数,但是也是遵循先定义后调用的原则,下面看示例:

#!/bin/bash

Lea()
{
    echo "Hello, I am Lea!"
}

Eden()
{
    echo "Hello, I am John!"
}

sayHello()
{
    Lea
    Eden
}

sayHello

结果如下:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-3.sh 
Hello, I am Lea!
Hello, I am John!

函数的返回值 

这里与其他编程语言有比较大的差别。

首先第一种就是不返回值,执行完操作就达到目的了。这在Shell中非常常见。

如果一定要返回值,有如下两种方式:

使用return返回

我们可以用return返回,然后使用$?系统变量获取到return的值

Shell的return返回只能返回0~255之间的整数,就是所谓的状态码。如果超过这个范围,返回的值就不对了,下面举个简单例子:

#!/bin/bash
func()
{
    return 257
}
func
echo $?

结果如下:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-4.sh 

1

将返回值输出到标准输出返回

在函数中,用户将需要返回的数据写入到标准输出(stdout),一般使用echo语句来完成,然后在调用程序中将函数的执行结果赋给一个变量,就是我前面文章讲的 命令替换 。

使用``或者$()命令获取函数输出到标准输出的值赋值给一个左值,请看示例:

#!/bin/bash
func1()
{
    echo "123"
}

result=$(func1)
result1=`func1`

echo $result
echo $result1

结果是:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-4.sh 
123
123

这种方式可以返回任意形式的值,不局限于整数,比return的方式更加的强大。

如果我们在一个函数里调用echo两次结果会是怎么样呢?看例子:

#!/bin/bash
func1()
{
    echo "Hello world"
    echo "123"
}

func1
result="$(func1)"
result1=`func1`

echo $result
echo $result1

结果是:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-4.sh 
Hello world
123
Hello world 123
Hello world 123

从结果上来看,返回的值把两个echo的输出结合在一起了,中间加了一个空格。

函数和别名 

在Shell中,与函数比较相似的一个概念是别名。一个别名是一个Shell命令的缩写或者映射,别名的语法如下:

#设置别名

alias  alias_name="command"

#删除别名

unalias alias_name

command命令是一条完整的命令,可以带参数。

与函数相比,别名的功能相对简单,其中主要区别如下:

  • 用户不能给一组命令指定别名
  • 别名中不能通过系统变量操作参数列表 

下面我们举个别名调用的例子:

#!/bin/bash
shopt -s expand_aliases
alias ls="ls -l"
ls

结果如下

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-5.sh 
total 16
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu  95 Jul 28 02:17 6-2.sh
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu 135 Jul 28 02:21 6-3.sh
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu 181 Jul 28 03:09 6-4.sh
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu  56 Jul 28 03:26 6-5.sh

如果没有第2行的 shopt -s expand_aliases,在Shell脚本中alias命令就是无效的。但是在Shell控制台中不需要,我们可以试试:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ alias ls="ls -l"
eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ls
total 16
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu  95 Jul 28 02:17 6-2.sh
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu 135 Jul 28 02:21 6-3.sh
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu 181 Jul 28 03:09 6-4.sh
-rwxrwxr-x 1 eden_ubuntu eden_ubuntu  56 Jul 28 03:26 6-5.sh

函数可以直接在Shell控制台输入定义:

删除函数

命令如下:

unset function_name

全局变量和局部变量

局部变量在函数中定义,在定义的变量名前加local关键字。除了这样,其他定义的变量都为全局变量。包括在函数中定义的变量。

函数参数 

之前有篇文章专门讲过传参:Shell系统学习之向Shell脚本传递参数

主要熟悉$#,$n,$@,$*,#?,getopts,getopt,shift的用法

间接传参

所谓间接传参就是通过一个变量的值当作另外一个变量的变量名来传参,中间绕了一下。语法如下:

${!var_name}

比方说存在两个变量

var=name
name=Eden

 我们可以将Eden这个值通过${name}传递过去,也可以用${!var}传递过去。

传递数组参数

严格的来说,Shell并不支持将数组作为参数传递给函数,但是用户仍然可以通过一些变通的方法数显数组的传递。

用户可以将数组的元素展开,然后作为多个由空格隔开的参数传递给函数。示例如下:

#!/bin/bash
func()
{
        echo "number of elements is $#."
        while [ $# -gt 0 ]
        do
         echo "$1"
         shift
        done
}

array=(a b "c d" e)
func "${array[@]}"

结果如下:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-6.sh 
number of elements is 4.
a
b
c d

 通过"${array_name[@]}"或者"${array_name[*]}"都可以实现目标

函数库文件

函数库文件的定义

创建一个函数库文件类似于编写一个Shell脚本,区别在于函数库文件只包含函数,没有外部可执行代码。举个简单的例子:

#!/bin/bash
error()
{
    echo "ERROR:" $@ 1>&2
}

上述内容就是一个函数库文件,只有函数。由于函数库文件是由主程序载入执行的,所以用户无需拥有可执行权限,有用可读权限即可。

函数库文件的调用

在Shell中,载入函数库文件的命令为 ,即一个原点,其语法如下:

. filename

 filename表示库文件的名称,可以使用相对路径,也可使用绝对路径。示例如下:

#!/bin/bash
#载入库文件
. 6-7.sh

error "cannot find file"

结果如下:

eden_ubuntu@edenubuntu:~/Documents/Shell/6$ ./6-8.sh 
ERROR: cannot find file 

必须在调用对应的函数之前载入对应的函数库文件,不然会报错:command not found.

小结

本篇文章主要讲述函数的定义,调用,返回值,传参,以及函数库文件的定义和调用。重点关注下返回值,传参,函数库文件的使用。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值