11.1. 简介

11.1.1. 什么是函数?

Shell 函数是一种将命令分组以便稍后执行的方法,使用一个名称来代表这个组,或者称为例程。例程的名称在 shell 或脚本中必须是唯一的。构成函数的所有命令都像常规命令一样执行。当将函数作为简单命令名称调用时,将执行与该函数名称关联的命令列表。函数在声明它的 shell 中执行:不会创建新进程来解释命令。

在命令查找期间,特殊内建命令优先于 shell 函数。特殊内建命令包括:break:.continueevalexecexitexportreadonlyreturnsetshifttrapunset

11.1.2. 函数语法

函数可以使用以下语法

function FUNCTION { COMMANDS; }

或者

FUNCTION () { COMMANDS; }

两者都定义了一个 shell 函数 FUNCTION。内置命令 function 的使用是可选的;但是,如果不使用它,则需要括号。

花括号之间列出的命令构成函数的主体。每当 FUNCTION 被指定为命令名称时,就会执行这些命令。退出状态是函数主体中执行的最后一个命令的退出状态。

Note常见错误
 

花括号必须与函数体之间用空格隔开,否则它们会被以错误的方式解释。

函数体应以分号或换行符结尾。

11.1.3. 函数中的位置参数

函数就像迷你脚本:它们可以接受参数,它们可以使用仅在函数内部已知的变量(使用 local shell 内建命令),并且它们可以将值返回给调用 shell。

函数也有一个用于解释位置参数的系统。但是,传递给函数的位置参数与传递给命令或脚本的位置参数不同。

当函数被执行时,函数的参数在其执行期间成为位置参数。特殊参数#会扩展为位置参数的数量,并被更新以反映这种变化。位置参数0保持不变。Bash 变量FUNCNAME在函数执行时被设置为函数名。

如果在函数中执行了 return 内建命令,函数将完成,执行将从函数调用之后的下一个命令恢复。当函数完成时,位置参数和特殊参数的值#将恢复为函数执行之前的值。如果给 return 提供了数字参数,则会返回该状态。一个简单的例子

[lydia@cointreau ~/test] cat showparams.sh
#!/bin/bash
                                                                                
echo "This script demonstrates function arguments."
echo
                                                                                
echo "Positional parameter 1 for the script is $1."
echo
                                                                                
test ()
{
echo "Positional parameter 1 in the function is $1."
RETURN_VALUE=$?
echo "The exit code of this function is $RETURN_VALUE."
}
                                                                                
test other_param

[lydia@cointreau ~/test] ./showparams.sh parameter1
This script demonstrates function arguments.
 
Positional parameter 1 for the script is parameter1.
 
Positional parameter 1 in the function is other_param.
The exit code of this function is 0.

[lydia@cointreau ~/test]

请注意,函数的返回值或退出代码通常存储在一个变量中,以便稍后可以探测它。系统上的 init 脚本经常使用探测RETVAL变量在条件测试中的技术,就像这个一样

if [ $RETVAL -eq 0 ]; then
	<start the daemon>

或者像来自/etc/init.d/amd脚本的这个例子,其中使用了 Bash 的优化特性

[ $RETVAL = 0 ] && touch /var/lock/subsys/amd

&& 之后的命令仅在测试证明为真时执行;这是一种表示 if/then/fi 结构的更简洁方式。

函数的返回代码通常用作整个脚本的退出代码。您会看到很多 init 脚本以类似 exit $RETVAL 的内容结尾。

11.1.4. 显示函数

当前 shell 已知的所有函数都可以使用不带选项的 set 内建命令显示。函数在使用后会被保留,除非在使用后被 unsetwhich 命令也显示函数

[lydia@cointreau ~] which zless
zless is a function
zless ()
{
    zcat "$@" | "$PAGER"
}

[lydia@cointreau ~] echo $PAGER
less

这是一种通常在用户的 shell 资源配置文件中配置的函数。函数比别名更灵活,并提供了一种简单易用的适应用户环境的方式。

这是给 DOS 用户准备的

dir ()
{
    ls -F --color=auto -lF --color=always "$@" | less -r
}