自在学
分类课程智能体订阅
分类课程AI导师价格
课程进度
7 / 25
上一节输入输出重定向下一节键盘技巧
自在学

© 2025 - 2026 自在学,保留所有权利。

公网安备湘公网安备43020302000292号 | 湘ICP备2025148919号-1

关于我们隐私政策使用条款

© 2025 自在学,保留所有权利。

公网安备湘公网安备43020302000292号湘ICP备2025148919号-1

编程Linux扩展与引号

扩展与引号

当我们按下回车键时,命令行里到底发生了什么“魔术”?这一部分,我们会用一个新的,也是唯一的命令 echo 来揭开这一切背后的秘密。echo 的功能很简单,就是把你给它的东西再显示出来。

每次你在命令行输入文本并敲下回车,Bash 都会在执行命令前,先对你输入的内容做一些“手脚”。我们之前见过 * 这种神奇的符号,它对于 Shell 来说意义非凡。这种把一个简单的符号变成另一堆内容的过程,就叫做“扩展”(Expansion)。

扩展与引号


理解扩展机制

什么是扩展?

扩展是Shell在执行命令前对输入内容进行预处理的过程。它会把特殊字符和模式转换成实际的值,然后再传递给命令执行。

扩展发生在命令执行之前,这意味着命令本身看到的已经是扩展后的结果,而不是你输入的原始内容。

让我们用 echo 来看看这个魔术。如果我们让它显示一段普通的文字,它会原样输出:

shell
$ echo this is a test
this is a test

这很直接。但如果我们给它一个 * 呢?

shell
$ echo *
Desktop Documents ls-output.txt Music Pictures Public Templates Videos

奇怪,* 怎么不见了?这正是“扩展”的魔力。当你按下回车时,Shell 会抢在 echo 命令之前,把 * 扩展成了当前目录下的所有文件名。 所以 echo 命令自己压根就没见到过 *,它见到的是 * 变身之后的结果,也就是一大串文件名,然后它忠实地把这些文件名给显示了出来。


路径名扩展

基本通配符

这种因为 * 这类通配符而发生的扩展,有个专门的名字,叫“路径名扩展”。它就像你打牌时出一张“王牌”,这张牌可以代表任何一张你想要的牌。在 Shell 里,* 就代表了任何文件名。 类似的,D* 就会扩展成所有以 “D” 开头的文件名:

shell
$ echo D*
Desktop Documents

更多通配符模式

匹配类型示例命令说明
匹配任意字符$ echo *显示当前目录下的所有文件和目录
匹配以特定字符开头的文件$ echo D*显示以 "D" 开头的文件和目录
匹配以特定字符结尾的文件$ echo *.txt显示以 ".txt" 结尾的文件
匹配单个字符$ echo file?.txt显示文件名为 file1.txt 到 file9.txt 的文件
匹配字符范围$ echo file[1-5].txt显示文件名为 file1.txt 到 file5.txt 的文件
匹配特定字符$ echo file[abc].txt显示文件名为 filea.txt, fileb.txt, filec.txt 的文件
匹配不在范围内的字符$ echo file[!abc].txt显示文件名不为 filea.txt, fileb.txt, filec.txt 的文件

通配符的常用组合

匹配类型示例命令说明
匹配所有隐藏文件$ echo .*显示当前目录下的所有隐藏文件
匹配所有目录$ echo */显示当前目录下的所有目录
匹配特定扩展名的文件$ echo *.{txt,md,pdf}显示当前目录下的所有以 .txt、.md 或 .pdf 结尾的文件
匹配多层目录中的文件$ echo **/*.txt显示当前目录及其子目录下的所有 .txt 文件

波浪号扩展 ~

基本波浪号扩展

还记得我们用 cd 命令时,那个波浪号 ~ 吗?它也是一种扩展,叫“Tilde 扩展”。~ 是个快捷方式,一个昵称,它会自动扩展成当前用户的家目录。这样你就不用每次都输入长长的 /home/your_name 了。

shell
$ echo ~
/home/me

波浪号扩展的变体

命令示例说明
$ echo ~显示当前用户的家目录
$ echo ~username显示特定用户的家目录
$ echo ~+显示当前工作目录
$ echo ~-显示上一个工作目录

算术扩展:让Shell帮你计算

基本算术运算

Shell 还能当计算器用,这时我们就要用到“算术扩展”。你只需要把数学算式放进 $(()) 里,Shell 就会先算出结果,再交给外面的命令。

shell
$ echo $((2 + 2))
4

它甚至能处理更复杂的运算,比如先算5的平方,再乘以3:

shell
$ echo $(((5**2) * 3))
75

不过要注意,Shell 的算术扩展只懂整数。所以 5/2 的结果会是2,而不是2.5。

算术扩展的运算符

运算类型示例命令说明
基本运算$ echo $((5 + 3))加法
$ echo $((10 - 4))减法
$ echo $((6 * 7))乘法
$ echo $((20 / 3))除法(整数)
$ echo $((17 % 5))取余
幂运算$ echo $((2 ** 8))2的8次方
位运算$ echo $((5 & 3))按位与
`echoechoecho((53))`
$ echo $((5 ^ 3))按位异或
$ echo $((~5))按位取反
$ echo $((5 << 2))左移
$ echo $((20 >> 2))右移
比较运算$ echo $((5 > 3))大于(返回1表示真)
$ echo $((5 == 3))等于(返回0表示假)

大括号扩展

基本大括号扩展

“大括号扩展”可能是最奇特的扩展了。它像一个模具,能让你根据一个简单的模式,创造出大量的文本。 比如,你想创建好几个文件夹,分别用A、B、C来命名:

shell
$ echo Front-{A,B,C}-Back
Front-A-Back Front-B-Back Front-C-Back

这个功能在创建有规律的文件或目录时特别方便。比如,一个摄影师想整理照片,他可以这样做来创建从2007年到2009年,每个月份的文件夹:

shell
$ mkdir {2007..2009}-{01..12}

只用一行命令,36个文件夹就瞬间创建好了。

大括号扩展的高级用法

大括号扩展示例

扩展类型示例命令结果说明
数字序列$ echo {1..10}生成从1到10的数字序列
$ echo {10..1}生成从10到1的递减数字序列
$ echo {1..10..2}生成从1到10,步长为2的数字序列
字母序列$ echo {a..z}生成从a到z的小写字母序列
$ echo {A..Z}生成从A到Z的大写字母序列
嵌套扩展$ echo {a,b}{1,2}生成组合序列:a1 a2 b1 b2
前缀和后缀$ echo file{1..3}.txt生成文件名序列:file1.txt file2.txt file3.txt
复杂模式$ echo {2007..2009}-{01..12}-{01..31}生成日期格式的组合序列

命令替换

基本命令替换

“命令替换”可以让你把一个命令的输出,当作另一个命令的输入。你只需要把第一个命令用 $() 包起来。 比如,你想知道 cp 命令到底藏在哪里,可以用 which cp 找到它的路径。然后,你可以把这个结果直接“喂”给 ls -l 命令来看它的详细信息:

shell
$ ls -l $(which cp)
-rwxr-xr-x 1 root root 71516 2007-12-05 08:58 /bin/cp

Shell 会先执行 $(which cp),得到结果 /bin/cp,然后整个命令就变成了 ls -l /bin/cp。

命令替换的常用模式

功能描述示例命令结果说明
获取命令路径$ ls -l $(which ls)显示 ls 命令的详细路径信息
获取当前日期$ echo “Today is $(date)”显示当前日期
获取系统信息$ echo “Kernel: $(uname -r)”显示当前内核版本
获取用户数量`echo“Users:echo “Users:echo“Users:(whowc -l)”`
获取文件数量`echo“Files:echo “Files:echo“Files:(lswc -l)”`
嵌套命令替换$ echo “Path: $(dirname $(which ls))”显示 ls 命令所在目录的路径

引号:关闭“魔术”的开关

既然 Shell 有这么多神奇的扩展,那如果我们不想要它自作主张地“变魔术”该怎么办呢?比如,我就想让 echo 显示一个 * 符号,而不是一堆文件名。

为了控制这些扩展,我们需要使用“引号”。引号就像是扩展功能的开关,可以精确地告诉 Shell 什么时候该“变魔术”,什么时候应该“保持原样”。

双引号

双引号 "" “是一个比较温柔"的开关。它会关闭大部分扩展,比如路径名扩展(* 不会变)和大括号扩展,但它会保留一些最有用的扩展,比如参数扩展($USER 依然会显示用户名)和命令替换($(cal) 依然会显示日历)。 这在处理带有空格的文件名时特别有用。没有引号,two words.txt 会被看成两个东西;有了双引号,"two words.txt" 就是一个完整的文件名。

我们看看双引号如何保留换行符,让日历正常显示:

shell
$ echo "$(cal)"
     二月 2008
日 一 二 三 四 五 六
                1  2
 3  4  5  6  7  8  9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29

单引号

如果你想让所有特殊字符都“失效”,让它们只作为普通文本出现,那就用单引号 ''。单引号是一个“彻底”的开关,它会关闭一切扩展。所见即所得。

shell
$ echo 'text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER'
text ~/*.txt {a,b} $(echo foo) $((2+2)) $USER

你看,所有东西都原样输出了。

反斜杠

有时候,我们只想关闭某一个字符的特殊功能,而不是一整段。这时可以用反斜杠 \,它被称为“转义字符”。它能让紧跟在它后面的那个特殊字符变成普通字符。 比如,你想在屏幕上显示 $ 符号,但又不希望它被当作变量扩展,就可以这样:

shell
$ echo “The balance for user $USER is: \$5.00”
The balance for user me is: $5.00

$USER 被正常扩展了,但 \$5.00 里的 $ 就因为前面的 \ 而被当作了普通的美元符号。

引号使用指南

引号类型示例命令结果说明
双引号$ echo “User: $USER, Date: $(date)”保留变量和命令替换,显示当前用户和日期
单引号$ echo 'User: $USER, Date: $(date)'完全按字面意思输出,不进行变量和命令替换
转义字符$ echo “Price: \$100, User: $USER”精确控制,显示美元符号和当前用户
混合使用$ echo “User: $USER, Path: '$(pwd)'”保留变量替换,路径使用单引号按字面意思输出

扩展的优先级

理解扩展的执行顺序是非常重要的,因为它决定了命令在执行时的行为。想象一下,扩展就像是一个接力赛,每个扩展都有自己的顺序和规则,只有按照正确的顺序进行,才能确保最终的结果是我们期望的。 就像在厨房里做饭一样,先切菜再炒菜,顺序错了,味道就不对了。

  1. 大括号扩展:{a,b,c}
  2. 波浪号扩展:~
  3. 参数扩展:$VAR
  4. 算术扩展:$((...))
  5. 命令替换:$(...)
  6. 路径名扩展:*, ?, [...]
  7. 引号处理:“...”, '...'

实践练习

让我们来做一些练习,巩固刚才学到的知识:

shell
# 1. 路径名扩展
$ echo *.txt
$ echo file[1-5].txt
 
# 2. 波浪号扩展
$ echo ~
$ cd ~/Documents
 
# 3. 算术扩展
$ echo $((10 + 5 * 2))
$ echo $((2 ** 10))
 
# 4. 大括号扩展
$ echo {1..5}
$ mkdir project-{a,b,c}
 
# 5. 参数扩展
$ echo $USER
$ echo ${USER:-guest}
 
# 6. 命令替换
$ echo “Current directory: $(pwd)”
$ ls -l $(which bash)
 
# 7. 引号使用
$ echo “Files: $(ls *.txt)”
$ echo 'Files: $(ls *.txt)'
$ echo “Price: \$99.99”
  • 理解扩展机制
    • 什么是扩展?
  • 路径名扩展
    • 基本通配符
    • 更多通配符模式
    • 通配符的常用组合
  • 波浪号扩展 ~
    • 基本波浪号扩展
    • 波浪号扩展的变体
  • 算术扩展:让Shell帮你计算
    • 基本算术运算
    • 算术扩展的运算符
  • 大括号扩展
    • 基本大括号扩展
    • 大括号扩展的高级用法
    • 大括号扩展示例
  • 命令替换
    • 基本命令替换
    • 命令替换的常用模式
  • 引号:关闭“魔术”的开关
    • 双引号
    • 单引号
    • 反斜杠
    • 引号使用指南
  • 扩展的优先级
  • 实践练习

目录

  • 理解扩展机制
    • 什么是扩展?
  • 路径名扩展
    • 基本通配符
    • 更多通配符模式
    • 通配符的常用组合
  • 波浪号扩展 ~
    • 基本波浪号扩展
    • 波浪号扩展的变体
  • 算术扩展:让Shell帮你计算
    • 基本算术运算
    • 算术扩展的运算符
  • 大括号扩展
    • 基本大括号扩展
    • 大括号扩展的高级用法
    • 大括号扩展示例
  • 命令替换
    • 基本命令替换
    • 命令替换的常用模式
  • 引号:关闭“魔术”的开关
    • 双引号
    • 单引号
    • 反斜杠
    • 引号使用指南
  • 扩展的优先级
  • 实践练习