声明
方式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
使用return
#!/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
echo
#!/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
.bashrc
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:实际测试中发现用不了,原因未知。