人人都会AI编程

自定义变量、变量引用、变量作用域

更新时间:2026-07-12

在 Linux 系统的 Shell 环境中,变量是存储临时数据、配置选项和脚本参数的基本单位。理解变量的定义、引用和作用域,是编写可靠 Shell 脚本的第一步。

1. 自定义变量

在 Bash 中,自定义变量的语法非常简单:等号两边不能有空格

name="Linux"          # 定义一个字符串变量
count=10              # 定义一个整型(实际上仍是字符串)
pi=3.14               # 定义浮点数(同样作为字符串处理)
readonly constant=100 # 定义一个只读常量

变量名通常使用大写(习惯约定),但小写也合法。如果需要包含空格或特殊字符,需要用引号包围:

greeting="Hello, World!"
file_path="/home/user/my documents/report.txt"   # 包含空格需用双引号

常用内置变量可以当做系统预设的自定义变量来使用,例如 $HOME$USER$PATH 等。你也可以修改它们(不建议随意修改系统变量):

PATH="$PATH:/opt/myapp/bin"   # 将自定义目录追加到 PATH 中

2. 变量引用

要获取变量的值,需要在变量名前加上 $ 符号,或者使用 ${} 进行明确界定:

echo $name           # 输出 Linux
echo "Hello, ${name}" # 输出 Hello, Linux
echo "${name} is great"  # 明确变量名边界,避免歧义

${} 形式在变量名与后续字符可能混淆时尤其重要:

filename="report"
touch "${filename}_2025.txt"   # 创建 report_2025.txt
# 如果写成 touch "$filename_2025.txt" 会去查找名为 filename_2025 的变量

除了直接引用,Bash 还提供一些常用的变量展开技巧:

  • 默认值${var:-默认值} 如果 var 未定义或为空,使用默认值。
  echo "Your name: ${username:-Guest}"   # 若未设置 username,则输出 Guest
  
  • 指定默认值并赋给变量${var:=默认值}
  : ${count:=0}   # 若 count 未设置,则赋值为 0
  
  • 错误提示${var:?错误信息},若 var 未定义则退出并打印错误信息。
  • 替换${var/pattern/replacement} 替换匹配的内容(仅一次),${var//pattern/replacement} 全局替换。

引用命令的输出要用命令替换 $(...),它实际上是将命令的输出赋给变量:

today=$(date +%F)
echo "Today is $today"

3. 变量作用域

在 Bash 中,变量的作用域默认是全局的:在一个 Shell 会话中定义的变量,会对当前 Shell 以及从这个 Shell 启动的所有子进程可见(前提是使用 export 导出)。

  • 默认变量不会是环境变量:直接在脚本中定义的变量,不会传递给子进程(如脚本中调用的其他命令或脚本)。要让子进程继承,必须用 export 将其标记为环境变量,或直接在赋值时使用 export
  myvar="hello"     # 只在当前 Shell 可见
  export myvar       # 现在子进程也能访问
  export var2="world"  # 定义并导出一步完成
  
  • 函数中的局部变量:在 Shell 函数内部,使用 local 关键字定义局部变量,其作用范围仅限于函数内部,不会覆盖外部的同名变量,也不会在函数返回后保留。
  #!/bin/bash
  global_var="I am global"

  myfunc() {
      local global_var="I am local"   # 遮蔽了外部同名变量
      echo "Inside function: $global_var"
  }

  myfunc
  echo "Outside function: $global_var"   # 仍然输出 I am global
  

如果没有 local,函数内的赋值就会直接修改外部的全局变量,这往往是脚本产生 Bug 的常见来源。

  • 通过括号 () 创建子 Shell 隔离作用域
  a=100
  ( a=200; echo "in subshell: $a" )   # 输出 200
  echo "in parent: $a"               # 输出 100,子 Shell 的修改不影响父 Shell
  

掌握变量的作用域控制,能够避免脚本中的意外副作用,特别是在编写复杂、会调用其他函数和脚本的自动化任务时至关重要。