bash参考手册之三(基本的Shell特性)续四


3.3 Shell函数

Shell函数是使用一个简单的名字来执行一组命令的方式。就像一个“普通”命令被执行似的。当一个shell函数的名称被用作一个简单的命令名称时,和该函数名相关的命令列表就被执行。 Shell函数在当前shell上下文中执行,没有创建新的进程。
函数声明使用的语法如下:
name () compound-command [ redirections ]

function name [()] compound-command [ redirections ]
这定义了一个名为name的shell函数。保留字function是可选的。如果使用了function保留字,括号是可选的。函数的body是复合命令compound-command(见复合命令)。该复合命令通常是被{和}包围的list,但也可以是上面列出的复合命令。当name被指定为一个命令的名称时,compound-command被执行。任何重定向(见重定向)在shell函数执行后执行。
使用带-f选项的unset内建命令(见Bourne shell的内建命令),可以删除函数的定义。
函数定义的退出状态是零,除非发生语法错误或已经存在一个具有相同的名称的函数。在执行时,函数的退出状态是函数体中执行的最后一个命令的退出状态。
请注意,由于历史的原因,花括号最常见的用法——包围函数体,必须使用空白或换行和函数体分隔。这是因为花括号本身是保留字,并只有用空格或其他shell元字符,把他们和命令列表分开时,才被识别为包围函数体。此外,当使用大括号时,list必须终止于分号,'&',或换行。
当一个函数被执行时,在执行过程中,函数的参数成为位置参数(请参阅位置参数)。特殊的参数“#”——被扩展成位置参数的个数——将被更新,以反映变化。特殊参数0是不变的。该函数被执行时,FUNCNAME变量的第一个元素被设置为函数名称。
函数和调用它的shell的执行环境在所有其他方面是相同的,除了这些以外:DEBUGRETURN陷阱不被继承,除非该函数已被使用内建命令declare设置trace属性,或内建命令set启用 -o functrace选项,(在这种情况下,所有的函数都继承DEBUGRETURN陷阱),ERR陷阱是不会继承的,除非使用shell 的 -o errtrace 选项启用。关于内建命令trap的描述,请参阅Bourne shell的内建命令。
FUNCNEST变量,如果被设置为一个大于0的数值,定义了函数的最大嵌套级别。函数调用超过限制,导致整个命令中止。
如果函数执行了内建命令return,函数执行完毕并继续执行函数调用后的下一个命令。任何与RETURN陷阱相关的命令在继续执行函数调用点之后的命令之前执行。当函数完成后,位置参数和特殊参数'#'的值恢复到他们在函数执行之前的值。如果return获得一个数字值,这就是该函数的返回状态;否则该函数的返回状态是在return前最后执行的命令的退出状态。
函数的局部变量,可以使用内建命令local声明。这些变量只对函数和它调用的命令是可见的。
函数的名称和定义可以使用带-f选项的declaretypeset内建命令(请参阅Bash内建命令)列出。 带-F选项的declaretypeset只列出函数名(如果shell选项extdebug启用,则列出的源文件和行号)。使用带-f选项的内建命令export,函数可以被导出,从而子shell可以自动获得它们的定义(见Bourne shell的内建命令)。需要注意的是shell函数和变量具有相同的名称时,可能会导致环境中多个相同名称的实体被传递到子shell中。必须当心这种情况,这会导致问题。
函数可以是递归的。 FUNCNEST变量可以用来限制的函数的调用栈的深度和限制函数调用的次数。默认情况下,递归调用的数量没有限制。


3.4 shell参数

•位置参数:shell的命令行参数。
•特殊参数:特殊字符来表示的参数。
parameter(参数)是一个存储值的实体。它可以是一个名字,一个数字,或下面列出的特殊字符之一。variable(变量)是使用name表示的参数。一个变量有value(值)和零或更多的属性。属性指定使用declare内建命令(Bash内建命令declare的描述)。
如果参数已被指定值,则是被设置了。空字符串是一个有效的值。一旦一个变量被设置,只能使用unset内置命令取消设置。
一个变量被指定的形式
name=[value]
如果没有给出value,该变量被指定为空字符串。所有value进行波浪线扩展,参数和变量扩展,命令替换,算术扩展和去除引号(详见下文)。如果该变量被设定了整数属性,即使没有使用表达式$((...)),value也被看作是一个算术表达式(见算术扩展)。不执行分词,“$@”是个例外,下面会解释。不执行文件名扩展。对于alias,declare,typeset,export,readonly,local等内建命令,赋值语句也可能以参数的形式出现。
在上下文中,赋值语句分配值到shell变量或数组索引(见数组)时,“+=”操作符可以用于向变量的当前值追加或增加。当'+='被施加到设置了整数属性的变量时,value被当作算术表达式,并加上变量的当前值。当“+=”应用到使用复合赋值的数组变量时(请参阅阵列),该变量的值不是被取消设置,(就像使用“=”的情况),新的值是被追加到数组的开始位置,比数组最大索引大1(对于索引数组来说),或者,对于联合数组而言,追加额外的键-值对。当应用到一个字符串变量时,value被扩展并追加到变量上。

3.4.1 位置参数

位置参数是由一个或多个数字,除了一位数字0以外,表示的参数。位置参数是在shell被调用时,被shell的参数赋值的,也可能会被内建命令set重新赋值。位置参数N可以被引用为${N},或$N——当N为一位数字时。位置参数不能使用赋值语句赋值。内建命令setshift用于对位置参数进行设置和取消设置(见shell内置命令)。执行一个shell函数时,位置参数被临时替换(见Shell函数)。
当位置参数由超过一位数字组成时,必须用大括号括起来。

3.4.2 特殊参数

shell中有几个特殊的参数。这些参数仅可以被引用,赋值给它们的是不允许的。
*
从1开始,扩展所有位置参数。当扩展发生在双引号中时,它扩展为一个单词——每个参数之间使用特殊变量IFS的第一个字符分隔。也就是说,“$ *”是相当于“$1c$2c...”,其中,c是IFS变量值的第一个字符。如果IFS未设置,参数用空格分开。如果IFS为空,参数中间没有分隔符。

@
从1开始,扩展所有位置参数。当扩展发生在双引号中时,每个参数扩展到一个单独的单词。也就是说,“$@”等同于“$1” “$2”...。如果双引号扩展出现在一个单词内,则扩展的第一个参数被连接到该单词的开头部分,并且扩展的最后的参数被连接到该单词的其余部分。如果没有位置参数时,“$@”和$@扩展为空(即,它们将被移除)。


扩展为十进制的位置参数的个数。


扩展为最近执行的前台管道的退出状态。

-
(连字符)。扩展为当前选项标志,即在调用时指定的标志。一般使用内建命令set,或由shell本身(如使用-i选项)设置的。

$
扩展为shell的进程ID。在()子shell,它扩展到调用shell,而不是子shell的进程ID。


扩展为最近执行的后台(异步)命令的进程ID。

0
扩展为shell或者shell脚本的名称。这是在shell初始化时设置的。如果bash是命令文件调用的(见Shell脚本),$0被设定为该文件的名称。如果bash以-c选项(参见调用Bash)启动,那么$0被设置为字符串被执行后的第一个参数,如果存在一个字符串的话。否则,它被设置为调用bash的文件名。

_
(下划线)。在shell启动时,被设定为通过环境或参数列表来调用shell或者shell脚本的绝对路径名。随后,扩展为前一个命令扩展后的最后一个参数。也设置为用来调用每一个命令的全路径名,和从环境中导出到该命令的全路径名。当检查邮件时,这个参数保存邮件文件的名称。


原文链接:http://www.gnu.org/software/bash/manual/bash.html#Shell-Functions


你可能感兴趣的:(shell)