文章目录

1、扩展

每次输入命令行按下​​Enter​​​键是,​​bash​​​都会在执行命令之前对文本进行多重处理。例如​​*​​​在​​shell​​​中被识别为多种意思。产生这个结果的处理过程称为扩展(expansion)。有了扩展功能,在输入内容后,这些内容将在​​shell​​对其执行之前被扩展成其它内容。

例如:​​echo​​​是​​shell​​的一个内置命令,它执行的任务是把文本参数内容打印到标准输出。

Linux--shell特性_文件名


传递给echo的任何参数都将显示出来,但不是所有情况都是这样的,如下:

Linux--shell特性_转义字符_02


为什么​​echo​​​不是输出​​*​​​呢?因为​​*​​​字符意味着“匹配文件名中的任意字符”,所以​​shell​​​在执行​​echo​​​命令前把​​*​​​扩展为其他内容(在这个例子中,扩展为当前工作路径下的所有文件名)。在按下Enter键的时候,​​shell​​​会在执行命令前自动扩展命令行中的所有符合条件的字符。因此​​echo​​​命令将不可能看到​​*​​​字符,只能看到​​*​​字符扩展后的结果。

1.1、路径名扩展

通过使用通配符来实现扩展的机制称为路径名扩展(pathname expansion)。

Linux--shell特性_文件名_03

1.2、波浪线扩展

如果把波浪线字符​​~​​用在一个单词的开头,那么它被扩展为指定用户的主目录名;如果没有指定用户命名,则扩展为当前用户的主目录。

Linux--shell特性_文件名_04

1.3、算术扩展

​shell​​​支持通过扩展来运行算术表达式,这允许我们把​​shell​​提示符当做计算器来使用:

Linux--shell特性_文件名_05


算术扩展使用格式:​​$((expression))​​;其中expression是指包含数值和算术操作符的算术表达式。

算术扩展只支持整数(全是数字,没有小数),但是可以执行很多不同的运行:

运算符

描述

+


-


*


/

除 (因为扩展只支持整数运算,所以结果也是整数)

%

取余

**

取幂

空格在算术表达式中是没有意义的,而且表达式是可以嵌套的。例如:

Linux--shell特性_双引号_06

1.4、花扩号扩展

有了花括号扩展(brace expansion)就可以按照花括号里面的模式创建多种文本字符串,例如:

Linux--shell特性_文件名_07


用于花括号扩展的模式信息可以包含一个称为前导字符(preamble)的开头部分和一个称为附言(postscript)的结尾部分。花括号表达式本身可以包含一系列逗号分隔的字符串,也可以包含一系列整数或者单个字符。

Linux--shell特性_转义字符_08


花括号扩展最普遍的应用是创建一系列的文件或者目录。比如说,摄影师有一个很大的图片集,想按年份和月份来对这些图片进行分组,那么要做的第一年是就是创建一系列以年月格式命名的目录。这样,这些目录名将会按照年代顺序排列,输出目录的一个完整的列表。

Linux--shell特性_文件名_09

1.5、参数扩展

参数扩展用在​​shell​​脚本中比直接用在命令行中更为有用。它的许多特性与系统存储小块数据命名的性能有关。很多这样的小块数据(称为变量[variable]会更合适)可用于扩展。例如:命名为USER的变量包含你的用户名,为了触发参数扩展,并显示出USER的内容,可以如下操作:

Linux--shell特性_转义字符_10

1.6、命令替换

命令替换可以把一个命令的输出作为一个扩展模式使用,例如:

Linux--shell特性_双引号_11


​ls​​​命令的运行结果作为​​echo​​命令的一个参数。

Linux--shell特性_双引号_12


在早期的shell程序中,存在命令替换的另一种语法格式,bash也支持这种格式,它用反引号代替美元符号和括号

Linux--shell特性_转义字符_13


2、引用

​shell​​提供了一种称为引用(quoting)的机制,用来有选择性地避免不想要的扩展。

Linux--shell特性_转义字符_14


因为$1是一个未定义的变量,所以参数扩展将把$1的值替换为空字符串。

2.1、双引号

如果把文本放在双引号中,那么​​shell​​​使用的所有特殊字符将失去它们的特殊含义,而被看成普通字符。字符​​$(美元符号)​​​、​​\(反斜杠)​​​、​​(反斜号)​​​除外。这就意味着单词分割、路径名扩展、波浪线扩展和花括号扩展都将失效,但是参数扩展、算术扩展和命令替换仍然生效。使用双引号能够处理文件名中包含空白的情况。假设不幸地有一个名为​​two words.txt​​的文件,如果在命令行使用该文件名,那么单词分割功能将把它当成两个独立的参数,而不是当成我们希望的单个参数,使用双引号可以阻止单词分割,得到预期的结果。另外,使用双引号甚至可以修复破损的文件名.

例如:​​ls -l "two words.txt"​注意:参数扩展、算术扩展和命令替换在双引号中依然生效

Linux--shell特性_转义字符_15

单词分割

默认情况下,单词分割会先查找是否存在空格、制表符以及换行符,然后把它们当作单词间的定界符。这就意味着没有用引号包含起来的空格、制表符以及换行符都不会被当成文本的一部分,而只是被当成分割符。

Linux--shell特性_转义字符_16


单词分割把这些单词分割成不同的参数,所以例子中的命令行被识别为命令后面跟着4个不同的参数。但是如果加上双引号,单词分割功能将失效,嵌入的空格将不再被当成界定符,而是被当成参数的一部分。

Linux--shell特性_文件名_17


一旦加上双引号,那么命令行将识别为命令后面只跟着一个参数。

2.2、单引号

如果我们希望一直所有的扩展,那么应该使用单引号。下面是不使用引号、使用双引号和使用单引号的情况对比。

Linux--shell特性_文件名_18


可以看到,随着引用级别的加强,越来越多的扩展将被抑制。

2.3、转义字符

有时候我们只是想要引用单个字符。这种情况可以通过在该字符前加上反斜杠来实现。这里的反斜杠称为转义字符。转义字符经常在双引号中用来有选择性的阻止扩展。

Linux--shell特性_双引号_19


转义字符也常用来消除文件名中某个字符的特殊含义。例如,文件名中可以使用在​​shell​​中通常具有特殊含义的字符。这些字符包括“$”、“!”、“&”、空格等。要想在文件名中包含特殊字符,可使用转义字符。

如果想要显示 反斜杠字符,可以通过使用两个反斜杠“\”来实现。需要注意的是,单引号中的反斜杠将失去它的特殊含义,而只是被当成一个普通字符。