Shell 函数是一种将命令分组以便稍后执行的方法,使用一个名称来代表这个组,或者称为例程。例程的名称在 shell 或脚本中必须是唯一的。构成函数的所有命令都像常规命令一样执行。当将函数作为简单命令名称调用时,将执行与该函数名称关联的命令列表。函数在声明它的 shell 中执行:不会创建新进程来解释命令。
在命令查找期间,特殊内建命令优先于 shell 函数。特殊内建命令包括:break、:、.、continue、eval、exec、exit、export、readonly、return、set、shift、trap 和 unset。
函数可以使用以下语法
function FUNCTION { COMMANDS; }
或者
FUNCTION () { COMMANDS; }
两者都定义了一个 shell 函数 FUNCTION。内置命令 function 的使用是可选的;但是,如果不使用它,则需要括号。
花括号之间列出的命令构成函数的主体。每当 FUNCTION 被指定为命令名称时,就会执行这些命令。退出状态是函数主体中执行的最后一个命令的退出状态。
![]() | 常见错误 |
---|---|
花括号必须与函数体之间用空格隔开,否则它们会被以错误的方式解释。 函数体应以分号或换行符结尾。 |
函数就像迷你脚本:它们可以接受参数,它们可以使用仅在函数内部已知的变量(使用 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 的内容结尾。
当前 shell 已知的所有函数都可以使用不带选项的 set 内建命令显示。函数在使用后会被保留,除非在使用后被 unset。 which 命令也显示函数
[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 } |