• Shell系统学习之函数


    目录

    函数

    什么是函数

    函数的定义

    函数的调用 

    函数的返回值 

    使用return返回

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

    函数和别名 

    删除函数

    全局变量和局部变量

    函数参数 

    间接传参

    传递数组参数

    函数库文件

    函数库文件的定义

    函数库文件的调用

    小结


    函数

    什么是函数

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

    函数的定义

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

    1. #第一种定义方式
    2. function_name ()
    3. {
    4. statement1
    5. ...
    6. }
    7. #第二种定义方式
    8. function function_name ()
    9. {
    10. statement1
    11. ...
    12. }

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

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

    command not found

    函数的调用 

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

    function_name param1 param2 ...

     下面看个简单的例子:

    1. #!/bin/bash
    2. #定义函数
    3. getCurrentTime()
    4. {
    5. echo "`date`"
    6. }
    7. #调用函数
    8. getCurrentTime

     结果如下:

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

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

    1. #!/bin/bash
    2. Lea()
    3. {
    4. echo "Hello, I am Lea!"
    5. }
    6. Eden()
    7. {
    8. echo "Hello, I am John!"
    9. }
    10. sayHello()
    11. {
    12. Lea
    13. Eden
    14. }
    15. 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之间的整数,就是所谓的状态码。如果超过这个范围,返回的值就不对了,下面举个简单例子:

    1. #!/bin/bash
    2. func()
    3. {
    4. return 257
    5. }
    6. func
    7. echo $?

    结果如下:

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

    1

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

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

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

    1. #!/bin/bash
    2. func1()
    3. {
    4. echo "123"
    5. }
    6. result=$(func1)
    7. result1=`func1`
    8. echo $result
    9. echo $result1

    结果是:

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

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

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

    1. #!/bin/bash
    2. func1()
    3. {
    4. echo "Hello world"
    5. echo "123"
    6. }
    7. func1
    8. result="$(func1)"
    9. result1=`func1`
    10. echo $result
    11. 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命令是一条完整的命令,可以带参数。

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

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

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

    1. #!/bin/bash
    2. shopt -s expand_aliases
    3. alias ls="ls -l"
    4. 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}

    比方说存在两个变量

    1. var=name
    2. name=Eden

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

    传递数组参数

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

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

    1. #!/bin/bash
    2. func()
    3. {
    4. echo "number of elements is $#."
    5. while [ $# -gt 0 ]
    6. do
    7. echo "$1"
    8. shift
    9. done
    10. }
    11. array=(a b "c d" e)
    12. 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脚本,区别在于函数库文件只包含函数,没有外部可执行代码。举个简单的例子:

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

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

    函数库文件的调用

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

    . filename

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

    1. #!/bin/bash
    2. #载入库文件
    3. . 6-7.sh
    4. error "cannot find file"

    结果如下:

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

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

    小结

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

  • 相关阅读:
    Android 使用Camera1实现相机预览、拍照、录像
    postgresql
    【星海出品】flask 与docker
    [云原生.docker安装]Centos7安装docker环境
    了解 Xcode 工作区、项目、方案和目标如何协同工作
    优化VUE Element UI的上传插件
    十、【分布式微服务企业快速架构】SpringCloud分布式、微服务、云架构之Eclipse 创建 Java 包
    Milvus 编译环境演进
    使用开源的zip.cpp和unzip.cpp实现压缩包的创建与解压(附源码)
    华为防火墙基础自学系列 | PKI核心部分CA
  • 原文地址:https://blog.csdn.net/MashiMaroJ/article/details/126039120