3.4 shell参数
一个参数是一个存储值的实体。 它可以是一个名称
,一个数字,或者下面列出的一个特殊字符。 一个变量是一个由名称
表示的参数。 一个变量有一个值
和零个或多个属性
。 属性是用declare
内置命令分配的(见4.2 Bash的内置命令中对declare
内置的描述)。
如果一个参数已经被分配了一个值,它就被设置了。空字符串是一个有效的值。一旦一个变量被设置,它只能通过使用unset
内置命令来取消设置。
一个变量可以通过以下形式的语句来分配给它
name=[value]
如果没有给出value,变量将被分配为空字符串。所有的value都要经过倾斜符号扩展、参数和变量扩展、命令替换、算术扩展和引号删除(见3 Shell参数扩展)。 如果变量设置了integer
属性,那么即使不使用$((…))
扩展,value也要作为一个算术表达式进行计算(见5 算术扩展)。不执行单词分割和文件名扩展。 赋值语句也可以作为alias
、declare
、typeset
、export
、readonly
和local
内置命令(声明命令)的参数出现。 当处于POSIX模式时(见6.11 Bash的POSIX模式),这些内置命令可以出现在command
内置命令的一个或多个实例之后,并保留这些赋值语句属性。
在赋值语句为 shell 变量或数组索引赋值的上下文中(参见 6.7 数组),'+='运算符可用于追加或添加到变量的先前值。这包括内置命令的参数,例如 declare
接受赋值语句(声明命令)。当‘+=’应用于已设置integer
属性的变量时,value将作为算术表达式求值并添加到变量的当前值,该值也会被求值。当使用复合赋值将‘+=’应用于数组变量时(参见6.7 数组),变量的值没有被取消设置(就像使用‘=’时一样),并且新的值被追加到数组,从大于 1 的位置开始,数组的最大索引(对于索引数组),或作为附加键值对添加到关联数组中。当应用于字符串值变量时,value 被扩展并且附加到变量的值。
一个变量可以使用-n选项分配给declare
或local
内置命令(见4.2 Bash的内置命令)的nameref
属性,以创建一个nameref,或对另一个变量的引用。 这使得变量可以被间接地操作。每当引用、分配、取消设置nameref变量或修改其属性时(除了使用或改变nameref属性本身),该操作实际上是在nameref变量的值所指定的变量上进行的。 nameref通常在shell函数中用来指代一个其名称作为参数传递给函数的变量。 例如,如果一个变量名称作为其第一个参数传递给shell函数,运行
declare -n ref=$1
在函数内部创建一个 nameref 变量ref
,其值为
作为第一个参数传递的变量名。
对ref
的引用和赋值,以及对其属性的更改,
被视为引用、赋值和属性修改
到其名称作为$1
传递的变量。
如果for
循环中的控制变量具有nameref属性,那么单词列表可以是一个shell变量的列表,当循环执行时,将为列表中的每个单词依次建立一个名称引用。 数组变量不能被赋予nameref属性。然而,nameref变量可以引用数组变量和下标数组变量。 Namerefs可以通过unset
内置程序的-n选项来取消设置(见4.1 Bourne Shell内置程序)。 否则,如果unset
以nameref变量的名字作为参数被执行,nameref变量所引用的变量将被取消设置。
1 位置参数
一个位置参数是由一个或多个数字表示的参数,而不是单一数字0
。位置参数在调用时从shell的参数中分配,并且可以使用set
内置命令重新分配。 位置参数N
可以作为${N}
引用,或者在N
由一个数字组成时作为$N
引用。位置参数不能用赋值语句来赋值,set
和shift
内置命令用来设置和取消它们(见4 Shell内置命令)。 当一个shell函数被执行时,位置参数被暂时替换(见3.3 Shell函数)。
当一个由一个以上的数字组成的位置参数被扩展时,必须用大括号括起来。
2 特殊参数
shell对几个参数进行了特殊处理。这些参数只能被引用,不允许对它们进行赋值。
*
-
($*) 扩展到位置参数,从1开始。 当扩展不在双引号内时,每个位置参数扩展到一个单独的字。 在执行的情况下,这些字会被进一步分词和文件名扩展。 当扩展发生在双引号内时,它扩展到一个字,每个参数的值由
IFS
特殊变量的第一个字符分隔。也就是说,"$*"
相当于"$1c$2c…"
,其中c是IFS
变量值的第一个字符。 如果IFS
未设置,参数之间用空格隔开。 如果IFS
为空,参数被连接,没有中间的分隔符。 @
-
($@) 扩展到位置参数,从1开始。 在执行分词的情况下,这将把每个位置参数扩展到一个单独的单词;如果不在双引号内,这些单词将被分词。 在不执行分词的情况下,这将扩展到一个单词,每个位置参数用空格分隔。 当扩展发生在双引号内,并且执行分词时,每个参数扩展到一个单独的单词。也就是说,
"$@"
相当于"$1" "$2" …
。 如果双引号扩展发生在一个词内,则第一个参数的扩展与原词的开头部分相连,最后一个参数的扩展与原词的最后部分相连。 当没有位置参数时,"$@"
和$@
扩展为空(即,它们被删除)。 #
-
($#)扩展为十进制的位置参数数。
?
-
($?) 扩展为最近执行的前台管道的退出状态。
-
-
($-,连字符。)扩展为调用时指定的当前选项标志,由
set
内置命令指定的,或由 shell 本身设置的标志(如-i选项)。 $
-
($$) 扩展为shell的进程ID。在子 shell 中,它扩展为调用 shell 的进程ID,而不是子shell。
!
-
($!) 扩展到最近被放入后台的作业的进程ID,无论是作为异步命令执行还是使用
bg
内建程序(见7.2 作业控制内置程序)。 0
-
($0) 扩展为shell或shell脚本的名称。这是在shell初始化时设置的。如果使用命令文件调用 Bash(见3.8 Shell脚本),
$0
被设置为该文件的名称。如果Bash是用-c选项启动的(见6.1 调用Bash),那么$0
被设置为要执行的字符串之后的第一个参数, 如果有一个的话。否则,它将被设置为用于调用Bash的文件名,如参数0所给出的。