当前位置:网站首页>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.
小结
本篇文章主要讲述函数的定义,调用,返回值,传参,以及函数库文件的定义和调用。重点关注下返回值,传参,函数库文件的使用。
边栏推荐
- Taosi TDengine 2.6+ optimization parameters
- 2022杭电多校第一场
- 2022 Hangzhou Electric Multi-School 2nd Game
- PyTorch安装及环境配置(Win10)
- 快解析结合用友时空
- Is R&D moving to FAE (Field Application Engineer), is it moving away from technology?Is there a future?
- 转行软件测试,报培训班3个月出来就是高薪工作,靠谱吗?
- PyQt5快速开发与实战 7.4 事件处理机制入门 and 7.5 窗口数据传递
- HCIP - MPLS VPN experiment
- els 方块向左移动
猜你喜欢

69. Sqrt(x)x 的平方根

积分专题笔记-曲线面积分三大公式

Unreal Engine Graphic Notes: could not be compiled. Try rebuilding from source manually. Problem solving

仿牛客网项目第二章:开发社区登录模块(详细步骤和思路)

The use of qsort function and its analog implementation

It is said that FPGA is high-end, what can it do?

积分专题笔记-与路径无关条件

深入浅出零钱兑换问题——背包问题的套壳

Excel xlsx file not supported两种解决办法【杭州多测师】【杭州多测师_王sir】

MySQL中使用IN 不会走索引分析以及解决办法
随机推荐
leetcode 剑指 Offer 47. 礼物的最大价值
Version management of public Jar packages
Scala
CSDN21天学习挑战赛
342 · Valley Sequence
Integral Topic Notes - Path Independent Conditions
The use of qsort function and its analog implementation
百度paddleocr检测训练
2022 Hangzhou Electric Multi-School 2nd Game
瑞吉外卖项目(五) 菜品管理业务开发
一文理解分布式开发中的服务治理
Test automation selenium (a)
虚幻引擎图文笔记:could not be compiled. Try rebuilding from source manually.问题的解决
【无标题】
[Fun BLDC series with zero basics] Taking GD32F30x as an example, the timer related functions are explained in detail
日志导致线程Block的这些坑,你不得不防
仿牛客网项目第一章:开发社区首页(详细步骤和思路)
The difference between DDR, GDDR, QDR
leetcode 剑指 Offer 21. 调整数组顺序使奇数位于偶数前面
leetcode 剑指 Offer 57. 和为s的两个数字