name () compound-command [ redirections ]
function name [()] compound-command [ redirections ]
Shell函数将命令列表组合作为一个单元执行。与命令组{ }和( )不同,定义Shell函数时不会理解执行compound-command。当将函数的名称被用作命令时,才会执行与该函数名称关联的命令列表。
Shell函数在当前Shell执行,不会为函数创建一个进程。但会为函数里的命令创建进程。
$ name () { ps -ef|grep 'name'; }
$ name
# 没有name进程
felix 169 153 0 21:34 tty1 00:00:00 grep --color=auto name
$
unset命令的-f选项可用于删除函数定义
unset -f name
定义函数时,只要语法没错,或没有与一个已经存在的只读的函数的名字冲突,函数定义的语句的退出状态是0
执行函数时,函数的退出状态就是函数体里最后执行的命令的退出状态。
执行函数时传递给函数的参数,成为函数执行过程中的位参。函数执行过程中,$#被扩展为位参个数。$0被Shell或Shell脚本的名称。FUNCNAME变量里的第一个元素是函数名称。
$ name () { echo $# $0 $FUNCNAME; }
$ name a b c
3 -bash name
内置命令return可以结束函数的执行。
与RETURN trap关联的命令会在函数执行结束前执行。
$ name () { trap "echo see you" RETURN;echo $# $0 $FUNCNAME;return;echo bye; }
$ name
0 -bash name
see you
$ name () { trap "echo see you" RETURN;echo $# $0 $FUNCNAME; }
$ name
0 -bash name
see you
如果给return命令数字参数,则设置了函数的返回状态; 否则,函数的返回状态是return之前执行的最后一条命令的退出状态。
函数被调用时,函数会继承调用者的shell环境,但不继承调用者定义的DEBUG, RETURN和ERR traps
如果设置变量FUNCNEST为大于0的数值,则定义最大函数嵌套级别。 超出此嵌套级别的函数调用将导致当前命令中止。
$ name () { echo $FUNCNEST; }
$ name
$ FUNCNEST=1
$ name
1
$ name1 () { name; }
$ name1
-bash: name: maximum function nesting level exceeded (1)
可以用local命令在函数体内声明局部变量。
$ func2 () { echo "var=$var in func2"; }
$ func1 () { local var=1;func2; }
$ var=0
$ func1
var=1 in func2
$ echo var=$var
var=0
$ var=0
$ func1 () { local var=1;unset var;echo "var=$var after unset"; }
$ func1
var= after unset
$ echo var=$var
var=0
$ var=0
$ func1 () { local var=1;func2; }
$ func2 () { unset var;echo "var=$var in func2"; }
$ func1
var=0 in func2
declare -f和declare -F可以列出函数名称和定义。
函数名称可以被export