Knighthana
文章108
标签144
分类7

文章归档

(KM)Shell中的单双引号

(KM)Shell中的单双引号

Shell中的单双引号

Shell 引号速查表(单引号 vs 双引号)

作者:DeepSeek


一句话核心

引号类型 内部是否展开变量 $var 内部是否展开命令 $(cmd) 内部是否识别转义 \n 能否包含同类型引号
单引号 '...' ❌ 不展开,原样输出 ❌ 不执行,原样输出 ❌ 不识别,\ 就是普通字符 ❌ 不能(无法转义)
双引号 "..." ✅ 展开 ✅ 执行 ✅ 识别常用转义(\$\"\n 等) ✅ 可以,但需转义 \"

详细说明

单引号 '...'

  • 绝对字面量:内部所有字符保持原样,没有任何特殊含义。
  • 不能嵌套单引号:即使写 '\'' 也不行(Shell 会把第一个 ' 和第二个 ' 配对,留下 \ 和第三个 ' 成为孤魂)。
  • 转义失效\n 输出两个字符 \n,而不是换行。
  • 典型用途:当字符串包含大量特殊字符($\"&* 等)且希望原样传递时。
1
2
3
echo '$HOME'          # 输出 $HOME
echo 'hello\nworld' # 输出 hello\nworld
echo 'It\'s fine' # 错误!无法转义单引号

双引号 "..."

  • 部分特殊字符保留
    • $var${var} → 变量值
    • $(cmd)`cmd` → 命令输出
    • \ 后跟 $"`\\n\t 等 → 转义序列
  • 可以安全包含单引号"It's fine" 完全合法。
  • 可以包含双引号:需要转义 \"
  • 典型用途:需要插入变量或命令结果,同时保留空格和部分转义。
1
2
3
4
echo "$HOME"          # 输出 /home/username
echo "It's fine" # 输出 It's fine
echo "He said \"Hi\"" # 输出 He said "Hi"
echo "line1\nline2" # 输出 line1 换行 line2

常见陷阱与误区

❌ 误区1:单引号内可以用 \' 转义单引号

事实:Shell 不识别 \' 作为转义。正确做法是结束单引号、写转义的单引号、再开始单引号:'It'\''s fine'
(解析为:'It' + \' + 's fine' → 得到 It's fine

❌ 误区2:双引号内所有字符都不特殊

事实$`"\(在某些情况下)仍有特殊意义。

❌ 误区3:单引号和双引号可以随意嵌套

事实:Shell 不支持真正的嵌套。"outer 'inner'" 实际上是一个双引号段内包含单引号字符(' 没有特殊意义)。而 'outer "inner"' 是一个单引号段内包含双引号字符。想要混合必须靠拼接。

✅ 正确做法:交替拼接

1
echo 'He said "It'\''s '"fine"'   # 输出 He said "It's fine"

分解:'He said "' + It + '\'' + 's ' + "fine" → 最终拼接。


何时使用哪种引号(决策树)

1
2
3
4
5
6
7
需要插入变量或命令结果?
├─ 是 → 使用双引号 "$var"
└─ 否 → 需要转义序列(\n、\t)?
├─ 是 → 使用双引号
└─ 否 → 字符串内是否包含双引号字符 "?
├─ 是 → 使用单引号(避免转义烦恼)
└─ 否 → 单引号更安全(完全原样)

实战速查命令

在终端中运行这些例子,对比输出:

1
2
3
4
5
6
7
8
9
10
11
# 单引号
echo '$PWD $(date) * \n' # 输出:$PWD $(date) * \n

# 双引号
echo "$PWD $(date) * \n" # 输出当前目录,日期,星号,换行

# 混合拼接
echo 'home: '"$HOME" # 输出 home: /home/username

# 在 bash -c 中传参(常见于 ZSH 调用 bash)
bash -c 'printf "%(%Y-%m-%d)T\n" -1' # 外层单引号保护整个字符串,内层双引号是 bash 自己的语法

一句话总结

  • 单引号 = 所见即所得(除了无法包含自身)
  • 双引号 = 允许变量和命令,保留转义
  • 混合 = 引号段自动拼接,每个段独立遵循自己的规则

把这个文件保存为 quotes_cheatsheet.txt 或放在笔记里,以后迷糊时 cat 一下即可。