方式1
function func { echo 'hi' echo 'hello' }
声明函数名为func的函数,注意这里的函数名之后必须接空格,再加上大括号
方式2
func(){ echo 'hi' echo 'hello' }
func为函数名,括号与大括号之间不需要空格
#!/bin/bash func(){ echo 'Hello' } func #Hello
- 函数名必须唯一
- 先声明,再使用
#输出上一条命令的状态码 echo $?
状 态 码 | 描 述 |
---|---|
0 | 命令成功结束 |
1 | 一般性未知错误 |
2 | 不适合的shell命令 |
126 | 命令不可执行 |
127 | 没找到命令 |
128 | 无效的退出参数 |
128+x | 与Linux信号x相关的严重错误 |
255 | 正常范围之外的退出状态码 |
130 | 通过Ctrl+C终止的命令 |
$?保存上个已执行命令的退出状态码 , 注意这里时上一条命令,对于function中包含多个命令也是返回function中最后一条命令的状态码
退出码不意味着函数执行成功,默认情况下,以最后一条命令的退出码作为函数的退出码
#!/bin/bash func(){ ls -l /a echo 'Hello' } func echo $? Hello 0 ls: cannot access '/a': No such file or directory
#!/bin/bash func(){ echo 'Hello' return 6 } func echo $? 6
return可以指定函数的退出状态码,但必须是0~255。
return 与 $? 之间不能再调用其他命令,否则还是返回最后一此执行命令的退出码
不能返回字符串
#!/bin/bash func(){ echo 'Hello' return 'hello' } func echo $? Hello 2 script.sh: line 4: return: hello: numeric argument required
#!/bin/bash func(){ echo 'Hello' } if [[ `func` = 'Hello' ]] then echo 'true' else echo 'false' fi echo $(func) true Hello
这里使用echo以及反引号(或$括号)将函数运行结果赋值给变量
这里最好只有一个echo ,否则比较结果时会不相等
#!/bin/bash func(){ echo 'hi' echo 'Hello' } if [[ `func` = "hi Hello" ]] then echo 'true' else echo 'false' fi echo $(func)
#!/bin/bash add() { echo $# echo $[ $1 + $2 ] } add 1 4 3
$#
获取参数的个数,$+索引(从1开始)
获得指定索引参数值
全局变量
#!/bin/bash func1(){ temp=10 } temp=0 func1 echo $temp #10
可以看到全局变量temp被函数内部修改了,这样可能导致很多意想不到的后果
#!/bin/bash func1(){ temp=10 } func1 echo $temp # 10
这个例子更能说明,函数内部声明的变量,外部也可以访问。所以函数内部的变量最好加上local
局部变量:local关键字
#!/bin/bash func1(){ local temp=10 } temp=0 func1 echo $temp # 0
这里输出的temp依然为0,local关键字保证了变量只局限在该函数中
#!/bin/bash func1(){ local tempArr=$1 echo ${tempArr[*]} } arr=(20 2 3 4 5) func1 $arr # 20
将数组变量作为函数参数,函数只会取数组变量的第一个值。
#!/bin/bash # array variable to function test function arrTest { local newarray #$@将所有变量拼成字符串,$()将命令结果赋值给变量,()括号重新组合为数组 newarray=($(echo "$@")) echo $newarray echo "The new array value is: ${newarray[*]}" } myarray=(1 2 3 4 5) arrTest ${myarray[*]} arrTest $myarray # 1 # The new array value is: 1 2 3 4 5 # 1 # The new array value is: 1
$@将所有变量拼成字符串,$()将命令结果赋值给变量,()括号重新组合为数组
返回数组
#!/bin/bash function arrTest { local newarray newarray=(1 2 3 30) echo ${newarray[*]} } newArr=`arrTest` echo $newArr twoArr=(`arrTest`) echo $twoArr #1 2 3 30 #1
#!/bin/bash function resc { if [ $1 -eq 1 ] then echo 1 else local temp=$[$1-1] local res=`resc $temp` echo $[ $res * $1 ] fi } result=`resc 5` echo $result
定义库文件
#文件名为test function addem { echo $[ $1 + $2 ] }
使用库文件
#! /bin/bash . ./test result=$(addem 10 15) echo $result
注意:
- 这里的库文件,并没有#! /bin/bash
- shell函数的作用域上,和环境变量一样, shell函数仅在定义它的shell会话内有效 。如果你在shell命令行界面的提示符下运行test shell脚本, shell会创建一个新的shell并在其中运行这个脚本。 而其他脚本无法使用。
- 这同样适用于脚本。如果你尝试像普通脚本文件那样运行库文件,函数并不会出现在脚本中。
- 使用函数库的关键在于source命令。 source命令会在当前shell上下文中执行命令,而不是
创建一个新shell。可以用source命令来在shell脚本中运行库文件脚本。这样脚本就可以使用库
中的函数了。- source命令有个快捷的别名,称作点操作符( dot operator)。要在shell脚本中运行myfuncs
库文件,只需添加下面这行:. ./test
。注意后面为脚本访问库文件的相对路径
一种方法是采用单行方式定义函数。 当在命令行上定义函数时,你必须记得在每个命令后面加个分号,这样shell就能知道在哪里是命令的起止了。
[root@localhost monitor]# function divem { echo $[ $1 / $2 ]; } [root@localhost monitor]# divem 100 10 10
另一种方法是采用多行方式来定义函数。在定义时, bash shell会使用次提示符来提示输入更多命令。用这种方法,你不用在每条命令的末尾放一个分号,只要按下回车键就行。 在函数的尾部使用花括号, shell就会知道你已经完成了函数的定义。
[root@localhost monitor]# function multem { > echo $[ $1 + $2 ] > } [root@localhost monitor]# multem 20 30 50
bash shell在每次启动时都会在主目录/root
下查找.bashrc文件
。
# .bashrc # User specific aliases and functions alias rm='rm -i' alias cp='cp -i' alias mv='mv -i' # Source global definitions if [ -f /etc/bashrc ]; then . /etc/bashrc fi ##bashrc文件中新增addem函数 addem(){ echo $[ $1+$2 ] }
在.bashrc文件中新增addem函数,则在任意位置打开的shell命令窗口都可以直接使用该函数
也可以使用source命令在.bashrc文件中,指定需要增加的库文件路径
shell还会将定义好的函数传给子shell进程,这些函数就自动能够用于该shell会话中的任何shell脚本了 。ps:实际测试中发现用不了,原因未知。