33、shell中的单引号、双引号

在 Shell(如 Bash)中,单引号 '...' 和双引号 "..." 都用于定义字符串,但它们对变量、转义字符、命令替换等的处理方式完全不同。

1、单引号 '...' —— 强引用(完全字面,原样输出)

  • 所有字符都被当作普通字符处理,包括 $`\! 等。
  • 变量不会被展开(不会识别变量,不会替换变量值)。
  • 命令替换不会执行。
  • 转义字符无效(反斜杠 \ 也被视为普通字符)。
name="Alice"
echo 'Hello $name'
// 输出:Hello $name ($name 不会被替换成 Alice)

2、双引号 "..." —— 弱引用(部分解释)

  • 会识别变量,允许变量展开(如 $var${var})。
  • 允许命令替换(如 $(command) 或 `command`)。
  • 允许部分转义:只有 $`"\ 和换行符等少数字符可以被反斜杠转义。
  • 其他特殊字符(如 *?[ 等)不会被通配符展开(即不会触发文件名扩展)。
name="Alice"
echo "Hello $name"
//  输出:Hello Alice

echo "Today is $(date)"
// 输出:Today is Fri Dec 5 16:20:00 CST 2025(实际执行 date 命令)

3、不加引号的情况

当字符串不加任何引号时,Shell 会对内容进行两次处理:

  1. 变量扩展(Variable Expansion)

  2. 单词分割(Word Splitting):Shell 会根据 IFS(Internal Field Separator,默认是空格、制表符、换行符)将未加引号的字符串分割成多个单词

  3. 路径名扩展(Globbing,通配符扩展):Shell 会将通配符(*?[])扩展为匹配的文件名

// 示例
name="John Doe"
echo Hello $name
// 输出: Hello John Doe              注意:这里实际上是两个参数传递给 echo
如:

单词分割(Word Splitting)

#!/bin/bash

files="file1.txt file2.txt file3.txt"

// ❌ 错误示范:不加引号
ls $files
// 等同于:ls file1.txt file2.txt file3.txt
// 如果文件都存在,正常执行

// ✅ 正确示范:加双引号
ls "$files"
// 尝试找名为 "file1.txt file2.txt file3.txt" 的文件,通常不存在

路径名扩展(Globbing)

// 假设当前目录有:file1.txt file2.txt file3.txt

echo *.txt
// 输出: file1.txt file2.txt file3.txt

// 对比加引号的情况
echo "*.txt"
// 输出: *.txt

 

4、区别

 

  • 单引号:原封不动;
  • 双引号:该变则变。
特性单引号 '...'双引号 "..."示例
变量扩展($var ❌ 不展开(原样输出) ✅ 展开(替换成值) name=World
echo '$name' 输出 $name
echo "$name" 输出 World
命令替换(`cmd` 或 $(cmd) ❌ 不执行 ✅ 执行并替换结果 echo 'Today is $(date)' 输出 Today is $(date)
echo "Today is $(date)" 输出 Today is Tue May 21 ...
转义字符(\n\t\$ 等) ❌ 无效(反斜杠视为普通字符) ✅ 部分有效(仅 \$`" 被转义) echo 'Hello\nWorld' 输出 Hello\nWorld
echo "Hello\nWorld" 输出 Hello 换行 World
原样输出 完全“所见即所得”(原样输出) 允许“动态内容”(部分原样) 单引号内所见即所得,所有字符都是字面量。

何时用单引号?何时用双引号?

场景推荐引号原因
纯静态文本,含 $`\ ✅ 单引号 防止意外展开
需要变量或命令替换 ✅ 双引号 支持动态内容
正则表达式 / JSON 字符串 ✅ 单引号 避免 $ 被误解析
传递含空格的文件名 ✅ 双引号 保持整体性(如 "$file"
posted @ 2025-12-05 16:31  chao_xiong  阅读(2)  评论(0)    收藏  举报