编程进阶网编程进阶网
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 基础组成体系
  • 程序编程原理
  • 异常和IO系统
  • 六大设计原则
  • 设计模式导读
  • 创建型设计模式
  • 结构型设计模式
  • 行为型设计模式
  • 设计模式案例
  • 面向对象思想
  • 基础入门
  • 高级进阶
  • JVM虚拟机
  • 数据集合
  • Java面试题
  • C语言入门
  • C综合案例
  • C标准库
  • C语言专栏
  • C++入门
  • C++综合案例
  • C++专栏
  • HTML
  • CSS
  • JavaScript
  • 前端专栏
  • Swift
  • iOS入门
  • 基础入门
  • 开源库解读
  • 性能优化
  • Framework
  • 方案设计
  • 媒体音视频
  • 硬件开发
  • Groovy
  • 常用工具
  • 大厂面试题
  • 综合案例
  • 网络底层
  • Https
  • 网络请求
  • 故障排查
  • 专栏
  • 数组
  • 链表
  • 栈
  • 队列
  • 树
  • 递归
  • 哈希
  • 排序
  • 查找
  • 字符串
  • 其他
  • Bash脚本
  • Linux入门
  • 嵌入式开发
  • 代码规范
  • Markdown
  • 开发理论
  • 开发工具
  • Git管理
  • 百宝箱
  • 开源协议
  • 技术招聘
  • 测试经验
  • 职场提升
  • 技术模版
  • 关于我
  • 目标清单
  • 学习框架
  • 育儿经验
  • 我的专栏
  • 底层能力
  • 读书心得
  • 随笔笔记
  • 职场思考
  • 中华历史
  • 经济学故事
  • 01.Bash简单介绍
  • 02.Bash基本语法
  • 03.Bash模式扩展
  • 04.Bash引号和转义
  • 05.Bash变量
  • 06.Bash字符串操作
  • 07.Bash算术运算
  • 08.Bash操作历史
  • 09.Bash行操作
  • 10.Bash目录堆栈
  • 11.Bash脚本入门
  • 12.Bash中read命令
  • 13.Bash条件判断
  • 14.Bash循环语法
  • 15.Bash函数用法
  • 16.Bash数组使用
  • 17.Bash中set和shopt
  • 18.Bash脚本除错
  • 19.mktemp和trap命令
  • 20.Bash启动环境
  • 21.Bash命令提示符

15.Bash函数用法

本章介绍 Bash 函数的用法。

简介

函数(function)是可以重复使用的代码片段,有利于代码的复用。它与别名(alias)的区别是,别名只适合封装简单的单个命令,函数则可以封装复杂的多行命令。

函数总是在当前 Shell 执行,这是跟脚本的一个重大区别,Bash 会新建一个子 Shell 执行脚本。如果函数与脚本同名,函数会优先执行。但是,函数的优先级不如别名,即如果函数与别名同名,那么别名优先执行。

Bash 函数定义的语法有两种。

# 第一种
fn() {
  # codes
}

# 第二种
function fn() {
  # codes
}

上面代码中,fn是自定义的函数名,函数代码就写在大括号之中。这两种写法是等价的。

下面是一个简单函数的例子。

hello() {
  echo "Hello $1"
}

上面代码中,函数体里面的$1表示函数调用时的第一个参数。

调用时,就直接写函数名,参数跟在函数名后面。

$ hello world
Hello world

下面是一个多行函数的例子,显示当前日期时间。

today() {
  echo -n "Today's date is: "
  date +"%A, %B %-d, %Y"
}

删除一个函数,可以使用unset命令。

unset -f functionName

查看当前 Shell 已经定义的所有函数,可以使用declare命令。

$ declare -f

上面的declare命令不仅会输出函数名,还会输出所有定义。输出顺序是按照函数名的字母表顺序。由于会输出很多内容,最好通过管道命令配合more或less使用。

declare命令还支持查看单个函数的定义。

$ declare -f functionName

declare -F可以输出所有已经定义的函数名,不含函数体。

$ declare -F

参数变量

函数体内可以使用参数变量,获取函数参数。函数的参数变量,与脚本参数变量是一致的。

  • $1~$9:函数的第一个到第9个的参数。
  • $0:函数所在的脚本名。
  • $#:函数的参数总数。
  • $@:函数的全部参数,参数之间使用空格分隔。
  • $*:函数的全部参数,参数之间使用变量$IFS值的第一个字符分隔,默认为空格,但是可以自定义。

如果函数的参数多于9个,那么第10个参数可以用${10}的形式引用,以此类推。

下面是一个示例脚本test.sh。

#!/bin/bash
# test.sh

function alice {
  echo "alice: $@"
  echo "$0: $1 $2 $3 $4"
  echo "$# arguments"

}

alice in wonderland

运行该脚本,结果如下。

$ bash test.sh
alice: in wonderland
test.sh: in wonderland
2 arguments

上面例子中,由于函数alice只有第一个和第二个参数,所以第三个和第四个参数为空。

下面是一个日志函数的例子。

function log_msg {
  echo "[`date '+ %F %T'` ]: $@"
}

使用方法如下。

$ log_msg "This is sample log message"
[ 2018-08-16 19:56:34 ]: This is sample log message

return 命令

return命令用于从函数返回一个值。函数执行到这条命令,就不再往下执行了,直接返回了。

function func_return_value {
  return 10
}

函数将返回值返回给调用者。如果命令行直接执行函数,下一个命令可以用$?拿到返回值。

$ func_return_value
$ echo "Value returned by function is: $?"
Value returned by function is: 10

return后面不跟参数,只用于返回也是可以的。

function name {
  commands
  return
}

全局变量和局部变量,local 命令

Bash 函数体内直接声明的变量,属于全局变量,整个脚本都可以读取。这一点需要特别小心。

# 脚本 test.sh
fn () {
  foo=1
  echo "fn: foo = $foo"
}

fn
echo "global: foo = $foo"

上面脚本的运行结果如下。

$ bash test.sh
fn: foo = 1
global: foo = 1

上面例子中,变量$foo是在函数fn内部声明的,函数体外也可以读取。

函数体内不仅可以声明全局变量,还可以修改全局变量。

#! /bin/bash
foo=1

fn () {
  foo=2
}

fn

echo $foo

上面代码执行后,输出的变量$foo值为2。

函数里面可以用local命令声明局部变量。

#! /bin/bash
# 脚本 test.sh
fn () {
  local foo
  foo=1
  echo "fn: foo = $foo"
}

fn
echo "global: foo = $foo"

上面脚本的运行结果如下。

$ bash test.sh
fn: foo = 1
global: foo =

上面例子中,local命令声明的$foo变量,只在函数体内有效,函数体外没有定义。

参考链接

  • How to define and use functions in Linux Shell Script, by Pradeep Kumar
贡献者: yangchong211
上一篇
14.Bash循环语法
下一篇
16.Bash数组使用