变量替换和变量默认值设置是紧密相关的,至少从概念出发是如此。程序员
参数扩张是将相似于变量的参数用它的值来替换。例如以“echo $VAR”的形式调用一个简单的变量。此外还有更多的特性能够访问。这个句法还包含一些没有扩展的特性,虽然这些特性自身颇有意义。首先,这类特性执行默认变量赋值。使用这些特性时,整个表达式须要用花括号括起来。shell
: ${VAR:=”some default”}bash
这些代码开始的冒号是一个正确执行非活动任务的shell命令。在这个句法中,它仅仅扩展了行中紧随其后的全部参数。本例中,只要是要在花括号内扩展参数值。函数
本行ongoing冒号中的参数是最有趣的部分;它是用花括号起来的一些逻辑的参数扩展。:=句法表示VAR变量将会和“some defalut”字符串进行比较。post
在这个表达式中,若是变量VAR尚未被设置,那么“:=”以后表达式的值将被赋给它,这个值多是一个数字,一个字符串,或者是另一个变量。编码
系统中的脚步可能须要将多个变量设置成默认值。程序员能够在一行中给多个变量设置默认值,而不是编码一组变量替换,这样也使得代码更加紧凑、易读。下面的例子包含了程序员须要执行的各类替换操做。第一个默认值是一个显示的串,第二个是一个显示的整数,第三个是一个已定义的变量。调试
: ${VAR:=”some default”} ${VAR2:=42} ${VAR3:=$LOGNAME}htm
这几个变量替换类型和前例中的:=句法相似。由于不一样替换类型的句法都是相同的,不过它们的意义却略有不一样,可能很容易混淆。在大多数状况下,代码中执行替换句法的地方,这些替换仅仅用某个值替换了变量,可是并无设置变量,也就是说变量并无被真正赋值。下面句法类型的定义在全部的shell联机资料中找到的,可是这些说明一般不是很清楚。blog
:=句法
在这种替换中,使用和前例中相同的:=句法来设置默认值。
username=””
echo “${username:=$LOGNAME}”
在使用“:=”进行比较时,username变量已经被定义了,可是它的值为空。所以,这里对echo命令使用了变量LOGNAME的值,即设置变量username的值为LOGNAME的值。
有了这个特殊的句法,只有当变量username已被定义,并且有一个实际的非空值时,变量username才会被设置为变量LOGNAME的值。
和前例的主要不一样是使用活动命令(echo)而不是被动的冒号来设置变量的默认值,当活动命令被调用时,默认赋值仍然会执行,并输出显示结果。
=句法
下面的语句和:=句法很是相似,可是没有冒号。
username=””
echo “${username=$LOGNAME}”
和前面同样,变量username已经被定义,可是它的值为空。在这个句法中,命令将会输出“echo”以后语句的执行结果。由于变量username虽然为空值,但已经被定义了,因此除了一个回车不会再有其余输出。只有当username变量彻底没有定义时,才会将其设置为变量LOGNAME的值。
当脚本或者函数须要依赖某些定义变量时,就要使用这种语法。它主要应用于登录。若是一个特定环境变量尚未被定义,就能够给它赋予脚本所须要的值。
:-句法
在这个命令中,由于变量username虽然已被定义可是为空值,echo语句将使用LOGNAME变量的值。
username=””
echo “${username:-$LOGNAME}”
这里username变量的值保持不变。这个命令和使用=句语法的不一样之处是,在此命令被执行前,仅仅在代码中的“${}”句法中作替换。也就是说,echo命令将输出LOGNAME变量的值,可是这个值不会被赋给username变量。
-句法
当删除上述的:-语句中的冒号,即变成-的时候,由于username变量已被定义,输出将为空。若是未定义,就会使用LOGNAME变量的值。还有一点也与:-句法相同,即username变量的值没有改变。
username=””
echo “${username-$LOGNAME}”
当脚本评价或检查系统环境的时,:-句法和-句法均可以使用。这两种检查基本上是相反的,它们用默认值替换变量,或者甚至于不依赖username变量是否已经被定义。若是脚本中急须要一组被定义的变量,也须要一些不应被定义的变量,那么在脚本执行任务以前组合这两种句法,确定能够实现正确的设置。
:?句法
使用:?句法时,若是username变量已被定义为非空值,在echo命令中就会使用username变量的值。若是username变量已被定义但却没有一个真正的值(也就是说非空)或者彻底未被定义,那么在echo命令中就会使用LOGNAME的值,而且脚本退出执行。
username=””
echo “${username:?$LOGNAME}”
若是把问号字符的参数改成某种错误字符,那这个语句就会在代码调试和查找未定义变量时变得颇有用。这段代码不只仅输出字符串,并且会显示代码在脚本中所在行的位置。
?句法
从:?句法中去掉冒号使用username变量没必要必定为非空值。若是username只被设置为一个空值,那么将使用这个空值。相反的,若是username变量没有被定义,则同前所述的:?句法,执行LOGNAME替换,脚本退出运行,并显示退出时所在代码行在脚本中的位置。
username=””
echo “${username?$LOGNAME}”
在脚本调试过程当中,须要检查变量是否已被定义或者是非空的是否,:?和?句法是很是有用的。这个代码最大的优势是脚本会从出错行退出,并且会显示出错误行行号。在要显示的文本中加上相似于“is undefined”或者“has a null value”信息,能够更清楚的说明脚本中的问题。
:+句法
和前面的例子相比,这个句法有相反的做用。这这是由于,只有当变量已被定义而不是未定义的时候,“${}”表达式才执行替换。
username=””
echo “${username:+$LOGNAME}”
若是这里的username变量已被定义并且非空,所以使用LOGNAME的值。若是username变量未定义,或者已定义但为空,则将使用空值。在任何状况下,username变量的值都不会改变。
+句法
若是 前例:+中的冒号,一旦变量username被定义,“${}”表达式都将使用LOGNAME的值;进行这个替换时,username变量不须要有一个实际的值(即非空值)。如
username=””
echo “${username+$LOGNAME}”
“:+”、“+”句法的用法不少是喝“:-”、“-”句法的用法相同的。最主要的区别是“:+”、“+”示例检查的是一个已定义的变量,而不是未定义的变量。这类相似于家法、减法——一枚硬币的两面。