Linux命令行低保-展开篇

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),可以用如下的方式:

    1. 为echo加上-e选项:echo -e "\a"
    2. 使用$' '包裹:echo $'\a'

参考资料

The Linux Command Line