购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

2.2 Shell基本语法

本节向读者介绍shell程序中的基本语法。与其他高级程序设计语言一样,Shell也可以使用变量;此外,Shell还可以使用通配符、引号;Shell程序也有自己的程序注释符,用来增加程序的可读性。

2.2.1 变量

在Shell中有三种变量:用户变量、系统变量和环境变量。其中,用户变量在编程过程中使用最多,系统变量在对参数和命令返回值进行判断时会经常使用,环境变量主要是在程序运行时需要设置。

1.用户变量

实际上,与所有的编程语言一样,Shell也是将值存放在变量中。Shell变量名由字母、数字、下画线组成,必须以字母或下画线开头。与其他编程语言不同的是,Shell变量不需要事先声明,只是在第一次用到它时进行创建并赋值。

Shell变量没有任何数据类型的概念,当向Shell变量赋值时,不管值是什么类型,Shell都简单地将它理解为字符串。例如,将数值1赋值给变量variable:

Shell只是把字符1(而不是数字1)存放到变量variable中,而根本不会理会存入变量的是一个整数值。

Shell会把“数值”型字符串依次转换为正确的数值,并按照正确的方式对它们进行操作。Linux是一个区分字母大小写的系统,因此,Shell变量也区分大小写,“variable”、“Variable”与“VARIABLE”是三个不同的变量。

需要注意的是,Shell变量的赋值号“=”两边不能有空格,可能部分C、C++的读者有在操作符两边加空格的良好编程习惯,但在Shell编程中则需要克服这一点,Shell变量的赋值不能加入这些空格。除此之外,等号右边的字符串也不能包含空格,如果字符串变量中需要使用空格,则必须用引号将它们括起来。

在Shell中,在变量前面使用“$”符号可以获得它的内容,用echo命令可以输出它的内容。“$”符号是Shell的特殊字符,如果“$”后面跟一个合法的变量名,则Shell会自动引用该变量的值。

提示

记住,无论何时,想要使用存储在Shell变量中的值时,一定要在该变量名前加上一个美元符号“$”。

Shell变量允许空值,当显示一个没有赋值过的变量时,显示结果为空,例如:

可以看到,Shell没有把blank变量替换成任何字符,因为blank变量的值为空。

说明

请读者注意区别Shell变量前的“$”符号和终端命令行提示符“$”。

echo命令也可以一次显示多个变量的值,多个变量之间使用空格或Tab隔开,例如:

另外,使用echo命令显示变量的值,而使用read命令可以读入变量的值。程序2.2是一个关于应用Shell用户变量的例子,代码如程序2.2所示。

首先,使用touch命令创建一个普通的文本文件echo_and_read.sh,然后,使用编辑器打开它,输入程序内容。

【程序2.2】关于读取和显示Shell用户变量的例子:echo_and_read.sh。

保存退出后,使用chmod命令修改文件的执行权限:

运行程序,输出结果如下:

此时,程序暂停运行,等待用户从终端输入,如输入字符串“shell program”(↙代表回车):

可以看到,通过read命令,从终端输入的字符串(以回车符结束)可以正确地保存到用户变量中。

Shell提供了参数置换能力以便用户可以根据不同的条件来给变量赋予不同的值。参数置换的变量有4种,这些变量通常与某一个位置参数相联系,根据指定的位置参数是否已经设置类决定变量的取值,它们的语法和功能分别如下。

(1)变量=${参数-word}:如果设置了参数,则用参数的值置换变量的值,否则用word置换。即这种变量的值等于某一个参数的值,如果该参数没有设置,则变量就等于word的值。

(2)变量=${参数=word}:如果设置了参数,则用参数的值置换变量的值,否则把变量设置成word,然后再用word替换参数的值。注意,位置参数不能用于这种方式,因为在Shell程序中不能为位置参数赋值。

(3)变量=${参数?word}:如果设置了参数,则用参数的值置换变量的值,否则就显示word并从Shell中退出,如果省略了word,则显示标准信息。这种变量要求一定等于某一个参数的值,如果该参数没有设置,就显示一个信息,然后退出,因此这种方式常用于出错指示。

(4)变量=${参数+word}:如果设置了参数,就用word置换变量,否则不进行置换。

所有这4种形式中的“参数”既可以是位置参数,也可以是另一个变量,只是用位置参数的情况比较多。

2.系统变量

Shell常用的系统变量并不多,但却十分有用,特别是在做一些参数检测的时候。表2.1列出了Shell下常用的系统变量的表示方法及其含义。

表2.1 系统变量

续表

下面是一个关于使用Shell系统变量的简单例子,代码如程序2.3所示。同样,首先使用touch命令创建一个文本文件sys_var.sh,然后使用编辑器打开它,输入程序内容。

【程序2.3】如何使用Shell的系统变量:sys_var.sh。

保存退出后,使用chmod命令修改文件的执行权限:

运行程序,输出结果如下:

3.环境变量

Shell环境变量是所有Shell 程序都会接收的参数。Shell程序运行时,都会接收一组变量,这组变量就是环境变量,最常见的环境变量是PATH、HOME、LOGNAME。环境变量通常采用大写字母命名,以便和用户在Shell脚本程序中定义的本地变量区别开来(后者一般使用小写字母命名)。Linux系统下Shell中常用的环境变量的含义描述如表2.2所示。

表2.2 环境变量

使用env命令可以查看系统中所有环境变量的值。

而在/etc/profile文件中可以添加、修改系统的环境变量,这种修改方式对所有的用户都生效,而且是永久性的。例如,在/etc/profile文件中增加环境变量CLASSPATH,只需在该文件中添加以下内容:

修改文件保存后,若想要马上生效还需要运行下面的命令:

否则只能在下次重新登录该用户时才生效。

另外,也可以直接使用export在Shell命令行下修改环境变量。但这只是对当前的Shell(如bash)或其子Shell有效,并且修改是临时性的,Shell关闭后变量就失效了,再打开新的Shell时没有这个变量,如果需要使用还需重新定义。

2.2.2 通配符

在Shell中除使用普通字符外,还可以使用一些具有特殊含义和功能的字符,称为通配符,在使用它们时应注意其特殊的含义和作用范围。

Shell的通配符主要用于模式匹配,如文件名匹配、路径名搜索、字串查找等。常用的通配符有“*”、“?”和括在方括号“[ ]”中的字符序列等,用户可以在作为命令参数的文件名中包含这些通配符,构成一个所谓的“模式串”,以在执行过程中进行模式匹配。这三个通配符的含义分别如下。

● “*”代表任意长度的字串,如“L*”匹配以L开头的任意字串。但应注意,文件名中的圆点(。)和路径名中的斜线(/)必须是显式的,即不能用通配符替代它们。例如,“*”不能匹配 .c,而“.*”才可以匹配 .c。

● “?”代表任何单个字符。

● “[ ]”指定了模式串匹配的字符范围,只要文件名中“[ ]”处的字符在指定的范围之内,那么这个文件名就与该模式串匹配。方括号中的字符范围可以由字符串组成,也可以由表示限定范围的起始字符、终止字符及中间连字符(-)组成。例如,f[a-d]与f[abcd]的作用相同。

Shell将把与命令行中指定的模式串相匹配的所有文件名都作为命令的参数,形成最终的命令,然后再执行这个命令。如果目录中没有与指定的模式串相匹配的文件名,则Shell将使用此模式串本身作为参数传给命令(这正是命令中出现特殊字符的原因所在)。

表2.3列举了这些通配符的具体实例及含义。

表2.3 通配符的实例及含义

需要注意的是,中间连字符(-)仅在方括号内有效,表示字符范围,若在方括号外面,就成为普通字符了。而“*”和“?”则只在方括号外有效,若出现在方括号之内,也失去了通配符的能力,成为普通字符。例如,模式 L[*?]abc中只有一对方括号是通配符,而“*”和“?”均为普通字符,因此,它匹配的字串只能是L*abc和L?abc。

注意

由于“*”、“?”和“[ ]”对于Shell来说具有比较特殊的意义,因此在文件名中不应出现这些字符,特别是在目录名中不要出现它们,否则可能导致Shell无穷递归地进行匹配。

2.2.3 引号

在Shell中引号分为3种:单引号,双引号和反引号。

1.单引号

由单引号括起来的字符都作为普通字符出现。特殊字符用单引号括起来以后,也会失去原有意义,而只作为普通字符解释。如下面的一系列命令:

可见,单引号中的“$”保持了其本身的含义,作为普通字符出现。而在一般情况下,“$”符号的含义是引用变量的值,PATH本身是一个Linux下的环境变量,其值是一系列的目录,当用户运行某个程序时,Linux在这些目录下进行搜寻。可以使用下面的命令查看变量PATH的值:

读者可仔细体会它与上面例子中的不同。

说明

对于本书中的注释,若无特殊说明,均采用以下约定。

在命令行、shell程序、Makefile(将在第3章介绍)中,使用“#”注释符,“#”后面为注释内容,读者要注意区别于Linux命令提示符“#”;而在C程序代码中,使用“/* */”的方式作为注释符。

2.双引号

双引号的作用与单引号类似,区别在于它没有那么严格。单引号告诉Shell忽略所有的特殊字符,而双引号只要求忽略大多数。具体来说,括在双引号中的三种特殊字符不被忽略:$、\ 和 ` 。即双引号会解释字符串的特别意义,而单引号则直接使用字符串。如果使用双引号将字符串赋给变量并反馈它,实际上与直接反馈变量并无差别。如果要查询包含空格的字符串,则经常会用到双引号。

看下面的例子:

从这个例子中可以清楚地看出无引号、单引号和双引号之间的区别。

第一种情况,显示变量x的值。由于x的值,即字符*匹配了当前目录(root目录)下的所有文件名,故显示变量x的值时,即显示了当前目录的所有文件名。

第二种情况,使用了单引号。单引号中的字符保持其本身的含义,这种情况最简单。

最后一种情况,使用了双引号。双引号告诉Shell在引号内照样进行变量名替换,所以Shell把 $x替换为*,因为双引号中不做文件名替换(忽略了非特殊字符),所以就把*作为要显示的值传递给echo命令,作为echo命令的参数。

另外,从例子中还可以看到Shell赋值的先后次序:Shell先进行变量替换,然后进行文件名替换,最后把这些替换值作为参数传递给命令。

3.反引号

反引号(`)字符所对应的键一般位于键盘的左上角,不要将其同单引号(')混淆。反引号括起来的字串被Shell解释为命令行,在执行时,Shell首先执行该命令行,并以它的标准输出结果取代整个反引号(包括两个反引号)部分。例如:

Shell执行echo命令时,首先执行`pwd`中的命令pwd,并用输出结果 /home/xyz取代`pwd`部分,最后输出替换后的整个结果。

利用反引号的这种功能可以进行命令置换,即把反引号括起来的执行结果赋值给指定变量。例如:

另外,反引号还可以嵌套使用。但需要注意的是,嵌套使用时内层的反引号必须用反斜线(\)将其转义。例如:

Shell首先执行内层嵌套的“who | wc -l”命令,然后将其结果3作为参数传递给下一个命令echo(外层反引号中的echo)。

2.2.4 注释符

在Shell编程或Linux的配置文档中,经常要对某些正文行进行注释,以增加程序的可读性。在Shell中,以字符“#”开头的正文行表示注释行。 AE4crHt/dxJ+EFyNOs6RtbFORLVYL6sE3CBw/5Q4I6xYeZyUbimpDzWUlBXAfC+g

点击中间区域
呼出菜单
上一章
目录
下一章
×