news 2026/9/13 3:56:42

Shell编程——函数

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Shell编程——函数

函数

    • 1、Shell函数的概念与作用介绍
    • 2、Shell函数的语法
    • 3、Shell函数的执行
    • 4、Shell函数的基础实践
    • 5、利用Shell函数开发企业级URL检测脚本

1、Shell函数的概念与作用介绍

在讲解Shell函数之前,先来回顾Linux系统中别名的作用。

[root@oldboy ~]# alias ssh='/etc/init.d/sshd'[root@oldboy ~]# ssh restart #<==执行ssh就相当于执行了/etc/init.d/sshd,最直接的好处就是简化了输入。 停止 sshd:[确定]正在启动 sshd:[确定]

函数也有类似于别名的作用,例如可简化程序的代码量,让程序更易读、易改、易用。

简单地说,函数的作用就是将程序里多次被调用的相同代码组合起来(函数体)​,并为其取一个名字(即函数名)​,其他所有想重复调用这部分代码的地方都只需要调用这个名字就可以了。当需要修改这部分重复代码时,只需要改变函数体内的一份代码即可实现对所有调用的修改,也可以把函数独立地写到文件里,当需要调用函数时,再加载进来使用。

使用Shell函数的优势整理如下:

  • 把相同的程序段定义成函数,可以减少整个程序的代码量,提升开发效率。
  • 增加程序的可读性、易读性,提升管理效率。
  • 可以实现程序功能模块化,使得程序具备通用性(可移植性)​。

对于Shell来说,Linux系统里的近2000个命令可以说都是Shell的函数,所以, Shell的函数也是很多的,这一点需要读者注意。

2、Shell函数的语法

下面是Shell函数的常见语法格式。

其标准写法为:

function函数名(){#<==作者推荐的书写函数的方法(带括号)指令...returnn}

简化写法1:

function函数名{#<==不推荐读者使用此方法(无括号)指令...returnn}

在Shell函数的语法中,当有function时,函数名后面的小括号“​(​)​”部分可以省略不写。

简化写法2:

函数名(){#<==不用function的方法指令...returnn}

在Shell函数的语法中,function表示声明一个函数,这部分可以省略不写。

3、Shell函数的执行

Shell的函数分为最基本的函数和可以传参的函数两种,其执行方式分别说明如下。

  • 1)执行不带参数的函数时,直接输入函数名即可(注意不带小括号)​。格式如下:
    函数名
    有关执行函数的重要说明:
    • 执行Shell函数时,函数名前的function和函数后的小括号都不要带。
    • 函数的定义必须在要执行的程序前面定义或加载。
    • Shell执行系统中各种程序的执行顺序为:系统别名→函数→系统命令→可执行文件。
    • 函数执行时,会和调用它的脚本共用变量,也可以为函数设定局部变量及特殊位置参数。
    • 在Shell函数里面,return命令的功能与exit类似,return的作用是退出函数,而exit是退出脚本文件。
    • return语句会返回一个退出值(即返回值)给调用函数的当前程序,而exit会返回一个退出值(即返回值)给执行程序的当前Shell。
    • 如果将函数存放在独立的文件中,被脚本加载使用时,需要使用source或“. ”来加载。
    • 在函数内一般使用local定义局部变量,这些变量离开函数后就会消失。
  • 2)带参数的函数执行方法,格式如下:
    函数名 参数1 参数2
    函数后接参数的说明:
    • Shell的位置参数($1、2 … 、 2…、2#、∗ 、 *、?及$@)都可以作为函数的参数来使用。
    • 此时父脚本的参数临时地被函数参数所掩盖或隐藏。
    • 当函数执行完成时,原来的命令行脚本的参数即可恢复。
    • 函数的参数变量是在函数体里面定义的。

4、Shell函数的基础实践

范例:开发脚本建立两个简单函数并调用执行。

[root@oldboy scripts]# cat 8_1.sh#! /bin/bash#定义两个函数,名字为oldboy和oldgirl。oldboy(){echo"I am oldboy."}functionoldgirl(){echo"I am oldgirl."}oldboy#<==在一个脚本里执行函数名调用函数。oldgirl#<==在一个脚本里执行函数名调用函数。

务必要先定义函数然后再执行函数,否则会报错,示例如下:

[root@oldboy scripts]# cat 8_2.sh#! /bin/basholdgirlfunctionoldgirl(){echo"I am oldgirl."}oldgirl[root@oldboy scripts]# sh 8_2.sh8_2.sh: line2: oldgirl:commandnot found#<==提示:第二行因为oldgirl函数不存在,所以就把oldgirl当作命令了,但是系统又没有oldgirl命令。I am oldgirl.

范例:分离函数体和执行函数的脚本文件(更规范的方法)​。

首先建立函数库脚本(默认不会执行函数)​。

使用cat命令追加多行文本,以将函数代码追加到系统的函数文件中,即/etc/init.d/functions,命令如下:

cat>>/etc/init.d/functions<<- EOF#<==here文档的另一种写法,此写法允许后面的EOF可以使用Tab键,而不顶格。oldboy(){echo"I am oldboy."}EOF#<==就是这里的EOF可以使用Tab键,而不顶格,但不能使用空格。

追加的函数代码如下:

[root@oldboy scripts]# tail -3 /etc/init.d/functionsoldboy(){echo"I am oldboy."}

然后开发执行脚本以调用上述函数。

[root@oldboy scripts]# cat 8_3.sh#! /bin/bash#加载函数所在的文件(functions是Linux系统内置的脚本函数库)[-f/etc/init.d/functions]&&./etc/init.d/functions||exit1#提示:可以用source 或“.”(点号)来加载脚本functions中的命令或变量参数等。#调用函数oldboy

执行结果如下:

[root@oldboy scripts]# sh 8_3.shI am oldboy.

范例:写出带参数的Shell函数示例。

这里通过建立函数oldgirl来做示例讲解,代码截图如图所示。

范例:将函数的传参转换成脚本文件命令行传参。

参考答案见图。

5、利用Shell函数开发企业级URL检测脚本

范例:将函数的传参转换成脚本文件命令行传参,判断任意指定的URL是否存在异常。

程序设计思路及实现:

  • 1)实现脚本传参,检查Web URL是否正常。
    [root@oldboy scripts]# cat 8_5.sh#! /bin/sh#判断传参个数是否为1个。if[$#-ne1]thenecho$"usage:$0url"exit1fi#利用wget进行访问测试,wget的相关参数在前面章节已经讲解过了。wget--spider-q-o/dev/null--tries=1-T5$1#<==-T指定超时时间,这里的$1为脚本的参数。if[$?-eq0]thenecho"$1is yes."elseecho"$1is no."fi
  • 2)将上述检测的功能写成函数,并将函数传参转换成脚本命令行传参,判断任意指定的URL是否存在异常。
    [root@oldboy scripts]# cat 8_5_1.sh#! /bin/shfunctionusage(){#<==帮助函数。echo$"usage:$0url"exit1}functioncheck_url(){#<==检测URL函数。wget--spider-q-o/dev/null--tries=1-T5$1#<==这里的$1就是函数传参。if[$?-eq0]thenecho"$1is yes."elseecho"$1is no."fi}functionmain(){#<==主函数。if[$#-ne1]#<==如果传入的是多个参数,则打印帮助函数,提示用户。thenusageficheck_url$1#<==接收函数的传参,即把下文main结尾的$*传到这里。}main $*#<==这里的$*就是把命令行接收的所有参数作为函数参数传给函数内部,是一种常用手法。
    执行结果如下:
    [root@oldboy scripts]# sh 8_5_1.shusage:8_5_1.sh url[root@oldboy scripts]# sh 8_5_1.sh www.oldboyedu.comwww.oldboyedu.com is yes.[root@oldboy scripts]# sh 8_5_1.sh www.oldgirl123.comwww.oldgirl123.com is no.

范例:将函数的传参转换成脚本文件命令行传参,判断任意指定的URL是否存在异常,并以更专业的输出显示,效果如图所示。


参考答案:

[root@oldboy scripts]# cat 8_6.sh#! /bin/sh./etc/init.d/functions#<==引入系统函数库。functionusage(){echo$"usage:$0url"exit1}functioncheck_url(){wget--spider-q-o/dev/null--tries=1-T5$1if[$?-eq0]thenaction"$1is yes."/bin/true#<==这里的action就是在脚本开头引入系统函数库后调用的。elseaction"$1is no."/bin/falsefi}functionmain(){if[$#-ne1]thenusageficheck_url$1}main $*

执行效果如下:

[root@oldboy scripts]# sh 8_6.sh www.oldboedu.com #<==输入错误地址。www.oldboedu.com is no.[失败][root@oldboy scripts]# sh 8_6.sh www.oldboyedu.comwww.oldboyedu.com is yes.[确定]
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/13 3:54:32

NumPy np.any()和np.all()原理与工程实践指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 3:54:00

Linux内存管理三层次:从虚拟内存到物理页分配

搞懂Linux内存管理,最怕的就是把它当成一个"平面"去看。很多人学了free、top、ps这些命令,看到内存占用率高了就紧张,看到Swap用了就慌,但内存管理系统本质上是三个层次叠在一起协同工作的:用户空间的虚拟内…

作者头像 李华
网站建设 2026/9/13 3:53:22

UUID字符串压缩原理与工程实践:熵值、长度、唯一性三重平衡

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/13 3:52:53

11.28数字文化现象解析与营销应用

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华