1、基本格式

shell函数的格式如下:

name () compound-command [redirection]
function name [()] compound-command [redirection]

shell函数实际上就是一个简单的shell命令,在当前shell执行,它代表了一组复合命令compound-command即函数体,函数体一般放在一对花括号中。关键字function可有可无,当使用了关键字function时,函数名name后面的一对圆括号是可选的。shell函数最后的重定向redirection也是可选的。

下面是几种shell函数的不同用法:

test_function()
{echo "test_function called"pwd
}function test_function2()
{echo "test_function2 called"pwd
}function test_function3
{echo "test_function3 called"pwd
}function test_function4()
{echo "test_function4 called"pwd
} > test_function.save

例子中,函数体都包括两个命令”echo“和“pwd”,test_function没有使用关键字function,test_function2使用了关键字function和圆括号,test_function3使用了关键字function但没有使用圆括号,test_function4将函数的标准输出重定向到了文件test_function.save。执行shell函数就像执行shell命令一样简单,命令名即函数名。

2、函数定义

在shell中,变量名可以和函数名相同,但容易引起混淆,所以变量名和函数名尽量不要相同。

$ foo=bar
$ foo() { echo "foo called"; }
$ echo $foo
bar
$ foo
foo called

同名函数可以多次定义,后面的定义会覆盖前面的定义,取消定义可使用命令“unset -f function_name”。

$ foo() { echo "11111"; }
$ foo() { echo "22222"; }
$ foo
22222
$ unset -f foo
$ foo
未找到 'foo' 命令,您要输入的是否是:命令 'fio' 来自于包 'fio' (universe)命令 'xoo' 来自于包 'xoo' (universe)命令 'fox' 来自于包 'objcryst-fox' (universe)命令 'goo' 来自于包 'goo' (universe)命令 'fog' 来自于包 'ruby-fog' (universe)命令 'zoo' 来自于包 'zoo' (universe)命令 'fgo' 来自于包 'fgo' (universe)命令 'fop' 来自于包 'fop' (main)
foo:未找到命令

在函数体中,对函数外的全局变量赋值时将改变这个变量的值,如果在函数体内的变量前使用关键字“local”,这个变量将被当作局部变量来使用,不会影响到同名的全局变量。

$ foo=1
$ bar=2
$ foobar() { foo=100; local bar=100; echo $foo $bar; }
$ foobar
100 100
$ echo $foo $bar
100 2

3、函数参数

shell函数的参数为位置参数,也就是说,这些参数都被编了序号,0表示shell脚本名或shell解释器名bash,1表示第一个参数,2表示第二个参数,等等,而参数的个数则保存在了一个特殊的参数“#”,另外特殊参数“*”和“@”也可以对函数参数进行扩展。在shell中访问变量或这些特殊参数使用美元符号“$”,下面举例说明函数参数的用法。

$ foo() { echo $# $0 $1 $2; echo $*; echo $@; }
$ foo a b c d
4 bash a b
a b c d
a b c d

使用关键字“shift”可以对位置参数进行移位,默认向左移动一位,效果如下:

$ foo() { echo $*; shift; echo $*; }
$ foo a b c d
a b c d
b c d

shift也可以带有一个参数,非负数,表示向左移动的位数,有效范围介于0到位置参数的总个数之间。

$ foo() { echo $*; shift 2; echo $*; }
$ foo a b c d
a b c d
c d

shell会对上面提到的几个特殊参数等作特殊处理,下面作详细介绍。

“*”:星号。扩展为从1开始的所有位置参数。如果它出现在双引号中,则扩展为一个包含每个参数的单词,参数之间用特殊变量IFS的第一个字符分隔,IFS即Internal Field Separator。也就是说,"$*""$1c$2c..."是等价的,其中c是特殊变量IFS的第一个字符,如果IFS没有设置,则参数之间用空格分隔,如果IFS为空,则参数直接相连,中间没有分隔。

$ foo() { echo $*; }
$ foo a b c d
a b c d
$ foo() { echo "$*"; }
$ foo a b c d
a b c d
$ IFS=
$ foo() { echo $*; }
$ foo a b c d
a b c d
$ foo() { echo "$*"; }
$ foo a b c d
abcd
$ unset IFS
$ foo() { echo $*; }
$ foo a b c d
a b c d
$ foo() { echo "$*"; }
$ foo a b c d
a b c d
$ IFS=:
$ foo() { echo $*; }
$ foo a b c d
a b c d
$ foo() { echo "$*"; }
$ foo a b c d
a:b:c:d

“@”:扩展为从1开始所有位置参数。如果它出现在双引号中,则每个参数都扩展为一个单词,也就是说,"$@""$1c""$2c"...是等价的,其中c是特殊变量IFS的第一个字符,如果IFS没有设置,则参数之间用空格分隔,如果IFS为空,则参数直接相连,中间没有分隔。

“#”:井号。扩展为位置参数的个数,用十进制表示。

“0”:数字0。扩展为shell或者shell脚本的名称,它是在shell初始化时设置的,如果Bash启动时带有包含命令的的文件名参数,"$0"就被设为该文件名,如果Bash启动时带有“-c”选项,则"$0"被设为待执行字符串后面的第一个参数(如果这个参数存在),否则,它就是用来启动Bash的文件名,即命令行的第一个参数。

“?”:问号。扩展为最近在前台执行的命令的退出状态。

$ uname -p
x86_64
$ echo $?
0
$ uname x
uname: 额外的操作数 "x"
Try 'uname --help' for more information.
$ echo $?
1

“!”:叹号。扩展为最近在后台异步执行的命令的退出状态。

$ echo $!$ uname -p
x86_64
$ echo $!$ uname -p &
[1] 20887
$ x86_64[1]+  已完成               uname -p
$ echo $!
20887

“$”:美元符号。扩展为当前shell的进程号,在子shell中,扩展为启动shell的进程号,而不是子shell的进程号。

$ foo() { echo $$; }
$ foo
20740
$ foo &
[1] 20849
$ 20740[1]+  已完成               foo
$ echo $$
20740

“-”:连字符。扩展为当前的所有选项,这些选项是启动时给定的,或者通过内部命令set打开的,或者由shell本身打开的。

$ foo() { echo $-; }
$ foo
himBH

”_“:下划线。在shell启动时,设为启动shell的绝对路劲,或者在执行环境或参数列表中所传递的待执行的shell脚本的绝对路径。随后,扩展为前一条命令的最后一个参数扩展后的值。还可设为每个已执行命令的绝对路径,这些路径是启动时指定的并且导入到命令的执行环境中。检查邮件时,这个变量保存邮箱文件的文件名。

$ touch t.sh
$ bash t.sh
$ echo $_
t.sh
$ foo() { echo $_; }
$ foo
t.sh
$ foo
foo

4、退出状态

函数定义本身也是一个shell命令,定义成功时其退出状态为0。在执行shell函数时,如果出现了关键字“return”,函数将提前结束,其退出状态为0;如果return后面是一个有效的数字(0到255),则shell函数的退出状态为这个数字;如果没有return,退出状态为shell函数体内执行的最后一个命令的退出状态。

5、扩展命令

先看如下使用了重定向的shell函数:

$ foo() { echo $*; } > foo.save
$ foo a b c d
$ cat foo.save
a b c d

上述foo函数把标准输出即函数参数重定向到了文件foo.save,此外,还可以使用shell扩展命令把foo函数的标准输出保存到shell变量中,shell扩展命令的格式为:

$ var=`your_command`
$ var=$(your_command)

例子:

$ foo() { echo $*; }
$ var=`foo a b c d`
$ echo $var
a b c d
$ var2=$(foo a b c d)
$ echo $var2
a b c d

【Bash百宝箱】shell函数相关推荐

  1. shell函数与数组(了解函数,递归函数运用,了解数组,创建基数和偶数数组,冒泡排序,调试命令)

    文章目录 shell函数 了解函数 函数定义 递归函数 举例子 shell数组 定义数组 数组包括的数据类型与数组操作 数组操作 举例(快速创建数组.奇数数组) 冒泡排序法 调试命令 set命令 ba ...

  2. linux shell 字符串 数组,bash shell函数返回数组字符串

    #!/bin/bash # script:getselfvar.sh # 每个脚本中都在末尾追加了一段特殊的域名ip序列,需要将这段序列存放到数组变量中,供 # 脚本使用,例子中的ip和域名是处理过的 ...

  3. bash shell函数中返回任意值的四种方法

    From: http://www.jbxue.com/article/11322.html 本文介绍下,在bash shell编程中,从函数中返回任意值的几种方法,有需要的朋友参考下. 在bash中, ...

  4. 【Bash百宝箱】shell内建命令之builtin、command、caller

    1.builtin 在shell中,内建(builtin)命令builtin,格式如下: builtin shell-builtin [arguments] builtin命令用以执行shell的内建 ...

  5. linux shell 函数库,bash shell 函数库

    bash shell 函数库ash由自由软件基金会,Inc.版权所有(C) 1989-2011. 语法 bash [options] [file] 描述 Bash是一种与sh兼容的命令语言解释器,它执 ...

  6. 【Bash百宝箱】shell内建命令之declare、typeset、local

    1.declare(typeset) 在shell中,内建(builtin)命令declare与typeset用法相同,格式如下: declare [-aAfFgilnrtux] [-p] [name ...

  7. Shell 函数、数组与正则表达式

    防伪码:白日依山尽,黄河入海流. 5.1  函数 格式: func() { command } 示例 1: #!/bin/bash func() { echo "This is a func ...

  8. linux使用shell函数扩充命令,Linux Shell系列教程之(十五) Shell函数简介 | Linux大学...

    摘要 函数可以将一个复杂功能划分成若干模块,从而使程序结构更加清晰,代码重复利用率更高. 高级语言都支持函数,Shell也不例外.今天就为大家介绍下Shell中函数相关用法. 函数可以将一个复杂功能划 ...

  9. Shell函数详解(函数定义、函数调用)

    Shell 函数的本质是一段可以重复使用的脚本代码,这段代码被提前编写好了,放在了指定的位置,使用时直接调取即可. Shell 中的函数和C++.Java.Python.C# 等其它编程语言中的函数类 ...

最新文章

  1. 纯干货|目前看到的BERT比较透彻的文章,强烈推荐
  2. 如何在Spring Boot中使用Hibernate Natural ID
  3. Web 设计:实现干净代码的12条定律
  4. CPropertyPage::OnSetActive()和OnKillActive()函数:属性页切换时的处理函数
  5. Android 应用程序发布流程注意事项(整理)
  6. 如何处理My lead fiori应用的buffer问题
  7. mac mysql 设置短命令_短小强大的8个命令,分分钟帮你提高工作效率!
  8. PyCharm2019.1.1安装(Win10)
  9. uni-app 背景图片动态设置
  10. 【数据结构和算法笔记】哈夫曼树的概念,构造和应用(利用哈夫曼编码压缩文本)
  11. Visual C++ 时尚编程百例013(CRect类)
  12. Eclipse汉化教程(各版本通用)
  13. 天堂2游戏登陆服务器源码分析1
  14. Linux之进程管理——查看进程
  15. ORA-12154: TNS: 无法解析指定的连接标识符
  16. 日程提醒app android,手机里有提醒日程安排的软件吗?
  17. 哪款蓝牙耳机通话效果好?蓝牙耳机通话效果最好排名
  18. PIPI1003: 最少钱币数c++
  19. jedis异常:Could not get a resource from the pool
  20. java中间件技术有哪些?

热门文章

  1. MIPS指令集和汇编
  2. FPGA AD0809 Verilog implement
  3. 电子传真虚拟化技术在企业的应用
  4. Omnipeek 空口抓包之无线ping包详细讲解,超详细
  5. 汽车软件通信中间件SOME/IP简述
  6. 应该在哪里购买域名?
  7. Kotlin从入门到『放弃』系列 视频教程
  8. Windows 权限维持学习记录
  9. Django模型层-多表操作
  10. 独家 | 蚂蚁金服漆远首谈刚完成的AI重大突破及紧缺人才,呼吁国内多点技术性强的大会,少点网红