02 · 变量与字符串

2026.10.08 · 🟢

目标:掌握变量定义/使用、单双引号的区别、字符串三大操作

🎯 今天要带走的三件事

  1. 赋值不加空格,取值才加 $ —— 这是 Shell 最反直觉的一点
  2. 单引号原样输出,双引号解析变量和转义
  3. 字符串三大操作:取长度 ${#s}、截子串 ${s:1:4}、找子串 expr index

一、定义变量

your_name="runoob"

命名规则

  • ✅ 只含字母、数字、下划线;不能以数字开头;大小写敏感
  • ✅ 常量习惯用大写:PI=3.14
  • ❌ 不能是关键字(if/then/for...)
  • ❌ 不含空格、不含特殊符号($、*、?)
# 正确
RUNOOB="www.runoob.com"
_var="123"
var2="abc"

# 错误
variable_name = value     # ❌ 等号两侧有空格
if="some_value"           # ❌ 用了关键字
?var=123                  # ❌ 特殊符号

用命令结果赋值

for file in `ls /etc`       # 反引号
for file in $(ls /etc)      # 推荐用 $(),更清晰

二、使用变量

your_name="qinjx"
echo $your_name
echo ${your_name}      # 推荐加花括号

为什么要花括号? 界定变量名边界:

for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done
# 不加花括号的话,$skillScript 会被当成一个变量(值为空)

💡 好习惯:所有变量都加 {}。

变量可重复赋值,但第二次赋值时不能带 $:

your_name="tom"
your_name="alibaba"    # ✅ 不带 $
# $your_name="alibaba" # ❌

三、只读变量与删除变量

# 只读:readonly
myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com"   # ❌ 报错:This variable is read only.

# 删除:unset(不能删只读变量)
myUrl="https://www.runoob.com"
unset myUrl
echo $myUrl    # 无任何输出

四、变量类型

类型 写法 说明
字符串 s='Hello' / s="Hello" Shell 中变量默认当字符串
整数 declare -i n=42 声明为整数,赋非整数会尝试转换
数组 arr=(1 2 3 4 5) 详见 03-数组与注释
关联数组 declare -A m; m["name"]="John" 键值对
环境变量 echo $PATH 系统/用户设置,影响执行环境
特殊变量 $0 $1 $# $? 详见 04-传递参数

五、Shell 字符串

字符串可用单引号、双引号,也可不用引号。

单引号 vs 双引号 ⭐

单引号 ' ' 双引号 " "
变量 ❌ 原样输出 ✅ 解析
转义字符 ❌ 无效 ✅ 有效(\n \")
内部单引号 不能出现单独的 ' 可以
# 单引号:原样输出
str='this is a string'

# 双引号:能解析变量和转义
your_name="runoob"
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str
# 输出:Hello, I know you are "runoob"! (\n 被解析为换行)

拼接字符串

your_name="runoob"
# 双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting $greeting_1       # hello, runoob ! hello, runoob !

# 单引号拼接(变量不解析)
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'
echo $greeting_2 $greeting_3
# hello, runoob !  hello, ${your_name} !

三大常用操作

string="runoob is a great site"

# 1. 取长度
echo ${#string}          # 13
echo ${#string[0]}       # 13(字符串场景等价)

# 2. 提取子串:${变量:起始:长度},下标从 0 开始
echo ${string:1:4}       # unoo

# 3. 查找子串:返回第一个匹配字符的位置(1 开始)
echo `expr index "$string" io`   # 4(i 先出现)

⚠️ expr index 用的是反引号 `,不是单引号 '!


🌙 今日作业

  • [ ] 定义一个变量,分别用单双引号拼接,观察输出差异
  • [ ] 用 ${#s}、${s:1:4} 对自己名字的拼音字符串做实验

自测题

  1. echo "I am good at $skillScript" 输出会是什么?怎么修?
  2. 单引号里写 $PATH,会输出路径吗?
  3. echo ${#string} 和 echo ${string:1:4} 分别做什么?
👉 参考答案 1. `$skillScript` 被当成一个未定义变量 → 输出 `I am good at `。修法:`${skill}Script`。 2. 不会。单引号内一切原样输出,输出的就是字面文字 `$PATH`。 3. 前者取字符串长度;后者从下标 1 开始截取 4 个字符。

🔗 关联

Shell-学习总览|上一课 → 01-Shell基础与第一个脚本|下一课 → 03-数组与注释