Linux的shell在执行命令时,首先会将命令中特定的内容进行展开(expansion
),然后才开始执行命令中的程序,可以被shell展开的内容种类多样,熟悉它们不光有助于理解命令与脚本的运行,更可以大大提高我们的效率。
检查展开结果最直观的方式就是使用echo
命令。特别地,shell并不会对正则表达式进行展开,而是交给接受正则表达式作为参数的命令自己处理
通配符
通配符的英文名是wildcards
(globbing
),它可以用来指定某一类特定的文件名,简化文件指令操作对名称的指定
注意,用通配符表示的文件名同样可以被/
分割来表示目录层次关系
wildcard |
用途 |
---|---|
* |
匹配任意多任意字符 |
? |
匹配任意单个字符 |
[characters] |
匹配在中括号内的任意单个字符 |
[!characters] |
匹配不在中括号内的任意单个字符 |
[[:class:]] |
匹配在中括号内类别中的单个字符 |
最后一项中,常见的类别有:
[:alpha:]
:字母[:digit:]
:数字[:alnum:]
:字母或数字[:lower:]
:小写字母[:upper:]
:大写字母
诸如[A-Z]
这样的范围来自更老的版本,慎用
波浪号
直接输入查看当前用户home
目录,后跟用户名查看特定用户的目录
算数表达式
写成$(([Expression]))
的形式
支持+
、-
、*
、/
、%
、**
,并且可以嵌套,也可以直接用单括号包住子表达式
花括号展开
前后缀可以为空,可以嵌套,会深度优先地展开,展开后具有相同的前后缀并且用空白彼此分隔,有以下几种常见的形式
[Preamble]{String1,String2,...}[Postscript]
[Preamble]{CharBegin..CharEnd}[Postscript]
[Preamble]{NumBegin..NumEnd}[Postscript]
应用举例:在mkdir
中作为参数,创建格式固定的大量目录
环境变量展开
命令中的环境变量也会被展开,也即$[VariableName]
,如果输入了不存在的环境变量,则会输出空行
命令替换
如果在一条命令中以$([Command])
的形式书写了另一条命令,那么内层的命令会先被执行,并将这一项展开为执行后的输出
举例:
ls -l $(which cp)
file $(ls -d /usr/bin/* | grep zip)
为了向下兼容旧版本的shell程序,也可以使用反引号``来包裹命令
禁用
背景:
shell在处理命令的时候不光进行了展开的工作,在此之前它还对输入进行了分词,因而多余的空白符可能不会按照我们的想法被处理
在实际使用中,我们有些情况下也不希望shell进行展开
解决:
双引号:shell对双引号中的内容只会对
$
、\
和`进行特殊对待,其它字符及代表的展开序列都不再展开与分词ls -l "seperate file.txt"
,就可以正确展示包含空白符的文件的详细信息,而不会分词后理解为两个参数echo "$(cal)"
,就可以将命令结果作为一个参数,保留cal命令输出中的各种空白符,不加双引号则会被命令替换成为若干个参数后一整行输出
单引号:shell对单引号中的内容完全保留原有模样
echo '$(cal)'
会原样输出echo的参数$(cal)
转义字符(
Escape Character
):反斜杠\
可以让$
等字符失效,作为普通的字符被shell对待,甚至包括反斜杠自己echo give me \$100
会将美元符号正确输出,而非理解成环境变量
如果要输出C那样的转义序列(
Escape Sequence
),可以用如下的方式:- 为echo加上
-e
选项:echo -e "\a"
- 使用
$' '
包裹:echo $'\a'