Shell函数
#!/bin/bash
定义
在被使用之前,函数必须已经被定义
如果函数名重复,后一个函数会覆盖前一个函数
function foo {
echo "foo"
}
# 也可以不写function关键字
bar {
echo "bar"
}
参数
运行函数就如同运行一个脚本,它也具有参数和返回值,和在Shell命令行中调用命令是类似的
同样使用$1, $#, $@
等变量获取参数
function mul {
# 连乘参数
local result="$1" # 局部变量
shift
while [ -n "$1" ]; do
((result *= "$1"))
shift
done
echo "$result"
}
function recursive_mul {
# 递归连乘
if [ $# -eq 1 ]; then
echo "$1"
else
local result="$1"
shift
((result *= $(recursive_mul "$@")))
echo "$result"
fi
}
function bar {
# 获取最后一个参数
if [ $# -gt 0 ]; then
echo "test result ${!#}"
fi
}
变量
一般的变量就不多说了
数组
可惜的是,在Shell中不能直接传递数组,也不能直接返回数组
function double {
local arr
arr=($@) # 获取
for ((i = $(($# - 1)); i >= 0; --i)); do
((arr[i] *= 2))
done
echo "${arr[*]}" # 返回
}
var=(1 2 3 4)
arr=($(double ${var[*]}))
echo ${arr[*]}
局部变量和全局变量
全局变量有着种种不便之处(诸如使用了无效的全局变量、意料之外的赋值等),不仅Shell,其他语言中也推荐尽量使用局部变量
默认情况下,在脚本中、函数中定义的变量都是全局变量
在函数中定义变量时可以使用local
关键字定义局部变量
返回值
获取函数返回值的方式有两种
- 使用
return
和$?
; - 使用
echo
和$()
(当然也可以用``
,但不推荐)。
二者并不对立,可以配合使用。严格意义上说,第二种方法不是返回值,而是捕获输出。
return
function foo {
echo 'test result'
return 1
}
如果没有指定return
一个值,那么就返回函数中最后一个命令的返回值(函数体不能为空,别想没有命令会怎么样了)。
与C语言等不同,return
的值不能直接获取,而是通过$?
查看。跟其他命令一样,返回值同样应该是一个0~255的状态码。
因为if, while, until
等命令是通过$?
来判断的,因此返回值可以直接用于这些流程中。但记住,如果不使用这些但又想获取返回值,请在函数结束后立刻查看$?
,否则它会被其他命令的返回值覆盖。
if foo; then
echo "yes"
else
echo "no"
fi
echo
与return
返回的状态码相比,不如说echo
和$()
更像C语言中的返回值,可以返回字符串、整数、浮点数等,因为它是通过捕获echo
的输出并保持到一个变量中来实现的。
result=$(foo)
# now result is "test result"
在其他地方使用函数
加载脚本文件到环境,可以使用source
命令,可以在命令行中使用,也可以在其他脚本文件中使用
source <script file>
# 就可以使用<script file>中的命令了
每次Shell启动时都会加载~/.bashrc
,可以在里面定义函数或是用source
加载脚本