当前位置:网站首页>Shell系统学习之函数
Shell系统学习之函数
2022-07-30 09:04:00 【edenliuJ】
目录
函数
什么是函数
函数就是将一组相对独立的代码集中起来,形成一个代码块,已完成一个具体的功能。和其他编程语言中的函数是一样的,从本质上讲,函数是一个函数名到某一块代码块的映射。
函数的定义
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结果如下:
[email protected]:~/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结果如下:
[email protected]:~/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 $?结果如下:
[email protected]:~/Documents/Shell/6$ ./6-4.sh
1
将返回值输出到标准输出返回
在函数中,用户将需要返回的数据写入到标准输出(stdout),一般使用echo语句来完成,然后在调用程序中将函数的执行结果赋给一个变量,就是我前面文章讲的 命令替换 。
使用``或者$()命令获取函数输出到标准输出的值赋值给一个左值,请看示例:
#!/bin/bash
func1()
{
echo "123"
}
result=$(func1)
result1=`func1`
echo $result
echo $result1结果是:
[email protected]:~/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
结果是:
[email protected]:~/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结果如下
[email protected]:~/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控制台中不需要,我们可以试试:
[email protected]:~/Documents/Shell/6$ alias ls="ls -l"
[email protected]:~/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,[email protected],$*,#?,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[@]}"结果如下:
[email protected]:~/Documents/Shell/6$ ./6-6.sh
number of elements is 4.
a
b
c d
e
通过"${array_name[@]}"或者"${array_name[*]}"都可以实现目标
函数库文件
函数库文件的定义
创建一个函数库文件类似于编写一个Shell脚本,区别在于函数库文件只包含函数,没有外部可执行代码。举个简单的例子:
#!/bin/bash
error()
{
echo "ERROR:" [email protected] 1>&2
}上述内容就是一个函数库文件,只有函数。由于函数库文件是由主程序载入执行的,所以用户无需拥有可执行权限,有用可读权限即可。
函数库文件的调用
在Shell中,载入函数库文件的命令为 . ,即一个原点,其语法如下:
. filename
filename表示库文件的名称,可以使用相对路径,也可使用绝对路径。示例如下:
#!/bin/bash
#载入库文件
. 6-7.sh
error "cannot find file"结果如下:
[email protected]:~/Documents/Shell/6$ ./6-8.sh
ERROR: cannot find file
必须在调用对应的函数之前载入对应的函数库文件,不然会报错:command not found.
小结
本篇文章主要讲述函数的定义,调用,返回值,传参,以及函数库文件的定义和调用。重点关注下返回值,传参,函数库文件的使用。
边栏推荐
猜你喜欢

自动化测试selenium(一)

The use of qsort function and its analog implementation

Circuit analysis: constant current source circuit composed of op amp and triode

ClickHouse

PyQt5快速开发与实战 8.1 窗口风格

MySQL Explain 使用及参数详解

硬件工程师

包、类及四大权限和static

leetcode 剑指 Offer 12. 矩阵中的路径

The FPGA based protocol 2: the I2C read and write E squared PROM
随机推荐
qsort 函数的使用及其模拟实现
树莓派_烧写Raspberry官方镜像系统
It is said that FPGA is high-end, what can it do?
Using IN in MySQL will not go through index analysis and solutions
聊聊 MySQL 事务二阶段提交
MySQL数据库题库
反射技巧让你的性能提升 N 倍
leetcode 剑指 Offer 22. 链表中倒数第k个节点
EMC过不了?都是PCB工程师的锅?
积分简明笔记-第一类曲线积分的类型
C#中Config文件中,密码的 特殊符号的书写方法。
仿牛客网项目第二章:开发社区登录模块(详细步骤和思路)
CSDN21天学习挑战赛
Version management of public Jar packages
快解析结合用友时空
Unreal Engine Graphic Notes: could not be compiled. Try rebuilding from source manually. Problem solving
How to run dist file on local computer
实施敏捷过程中这些常见的问题你可曾遇到?
How to use Jmeter to carry out high concurrency in scenarios such as panic buying and seckill?
激活数据潜力 亚马逊云科技重塑云上存储“全家桶”