第二十三章 Shell的基础语法
在所有的编程语言中都涉及变量和常量以及数据类型和函数等的语法,Shell中也是如此,只是与大多数编程语言较为不同。
变量与常量
当Shell碰到一个变量时,会自动创建该变量。在很多编程语言中,使用变量之前必须先声明或定义。Shell对此要求不严格。
例如:
先将foo赋值为yes,然后通过echo命令回显foo变量的值
foo="yes"
echo $foo
命令输出结果如下:
yes
本例中,创建变量foo并进行赋值,说明,通过echo输出结果可以看出变量foo赋值成功。在通过另一个例子,打印一个没有定义或声明并且没有赋值的变量:
echo $foo1
命令输出结果为一个空行,没有报错说明Shell变量可以未经声明或定义,直接创建。
变量命名规则:
变量名可以包含数字字符和下画线。
变量名的第一个字符只能是字母或下画线。
变量名中不允许出现空格符和标点符号。
变量一词暗示了其值可以该变,在很多应用程序中,变量就是这么用的。常量和变量一样,有名称,也有值。两者的区别是常量的值不能改变。例如在几何计算中,可以定义PI为常量,将其赋值为3.1415,不再在程序中到处使用具体数值。Shell并不区分变量和常量,只能通过书写格式进行区别,常量使用大写字母表示,变量使用小写字母表示。
Shell还提供了一种强制常量不变性(immutability)的方法,这是通过使用带有-r选项(read-only)的内建命令declare实现的,例如为变量TITLE赋值:
declare -r TITLE=“Page Title”
Shell会阻止之后对TITLE的赋值操作。这个特征只有在正式的脚本中才会看到它。
为变量与常量赋值
变量的复制方式如下:
variable=value
其中,variable是变量名,value是字符串。Shell不同于其他编程语言并不在意变量的数据类型,它将一切都视为字符串。可以使用带有-i选项的declare命令强制Shell只能赋值为整数,这种做法很少见。
Shell变量的值是可以通过字符串表示的任意值,例如:
a=z #将字符串z赋给变量a
b=“a string” #内嵌空格符的字符必须放入双引号中
c=“a string and $b” #赋值中包含其它扩展(例如,变量扩展)
d=“$(ls -l foo.txt)” #命令的执行结果
e=$((5 * 7)) #算术扩展
f=“\t\ta string\n” #转义序列,例如制表符、换行符
在一行中也可以完成多个变量的赋值。
a=5 b=“a string”
如果变量名由于其所在的上下文而产生歧义,花括号就能发挥作用。例如将文件myfile重命名为myfile1:
mv "$filename" "$filename1"
Shell会将mv命令的第二个参数解释为一个新变量(内容为空)。解决方法如下:
mv “ f i l e n a m e " " filename" " filename""{filename}1”
在两边添加花括号之后,Shell就不会认为末尾1属于变量名的一部分了。
将变量名和命令替换置于双引号内,以此限制Shell对其进行单词分割(word-splitting)操作,这是一种很好的做法。如果变量中可能包含文件名,双引号尤为重要。
Shell函数
Shell和其它编程语言一样可以声明和定义函数,函数就是用来实现特定功能并且包含参数列表以及返回值的一个段代码,但是Shell中的函数参数列表。Shell有两种函数语法形式,一种比较正式:
function name {
commands
return
}
另一种比较简单(通常也是首选):
name () {
commands
return
}
其中name是函数名称,commands是函数包含的一系列命令。这两种形式都是等价的,可以交换使用。
例如:做一个演示
代码如下:
function step2 {
echo “Step 2”
return
}
echo “Step 1”
step2
echo “Step 3”
执行结果如下:
本例首先通过echo打印Step 1 然后调用函数step2打印Step 2最后通过echo打印Step 3。
局部变量
在目前所编写的Shell脚本中,所有的变量(包括常量)都是全局变量。在整个程序执行期间一直存在。在Shell函数内部往往需要局部变量。局部变量只能定义其的Shell函数有效,一旦Shell函数终止,就不复存在。
局部变量可以通过local进行声明格式如下:
local variable
下面例子演示局部变量的定义和用法: 代码如下:
#!/bin/bash
#local-vars: 演示笨的变量的脚本
foo=0 # global variable foo
funct_1 () {
local foo #funct_1局部变量foo
foo=1
echo "funct_1: foo = $foo"
}
funct_2 () {
local foo #funct_2局部变量foo
foo=2
echo "funct_2: foo = $foo"
}
echo "global: foo = $foo"
funct_1
echo "global: foo = $foo"
funct_2
echo "global: foo = $foo"
运行结果如下:
从运行结果可以看出funct_1和funct_2的变量foo不同,说明可以通过local声明局部变量并且Shell中支持局部变量。
Shell函数是别名的较好替代,实际上也是创建供个人使用的轻量命令的首选方法。别名受限于其所支持的命令类型和Shell特征,而任何只要能写进脚本的内容,Shell函数都支持。例如,为.bashrc文件创建一个类似ds的函数:
ds () {
echo “Disk Space Utilization For $HOSTNAME”
df -h
}