Shell 变量声明与作用域

声明方式一览

方式作用域子进程继承典型场景
a='1'当前 Shell 局部变量临时计算、循环计数器、函数内局部状态
export a='1'环境变量(全局)配置子进程行为(PATH、HOME、LANG)
declare a=1当前 Shell 变量显式声明,可配合 -i -a -A 等类型标志
local a=1函数内局部变量函数内部使用,避免污染全局命名空间
readonly a=1只读变量取决于是否 export常量定义,不可修改
a='1' command临时环境变量✅(仅对 command 生效)单条命令的临时环境配置

详细说明

1. 基本赋值 a='1'

最基础的形式,变量仅在当前 Shell 进程内可见,子进程无法访问。

a='hello world'
echo $a               # 输出: hello world
bash -c 'echo $a'     # 输出:(空,子进程看不到)

2. 环境变量 export a='1'

将变量标记为环境变量,当前 Shell 及所有子进程均可见

export PATH="/usr/local/bin:$PATH"   # 子进程继承 PATH
export a='hello'
bash -c 'echo $a'                    # 输出: hello(子进程可见)

export 的本质是两步操作:

a='hello'
export a         # 标记变量 a 为导出属性

3. 一次性环境变量 a='1' command

变量仅在命令的子进程中存在,不影响当前 Shell:

LANG=en_US.UTF-8 python3 script.py    # 仅该 Python 进程使用英文环境
echo $LANG                            # 当前 Shell 的 LANG 不受影响

4. declare 类型声明

Bash 内置命令,可显式声明变量并指定类型:

declare -i num=10        # 整数类型(算术运算无需 $(( )))
declare -a arr           # 普通数组
declare -A map           # 关联数组(Bash 4.0+)
declare -r const=42      # 只读(等同 readonly)
declare -x env_var=foo   # 导出(等同 export)
declare -p variable      # 查看变量属性

5. local 函数内局部变量

仅在函数内部生效,函数退出后自动销毁:

myfunc() {
  local count=0         # 函数内局部变量
  count=$((count + 1))
  echo $count           # 输出: 1
}
echo $count             # 输出:(空,外部不可见)

6. readonly 只读变量

一旦赋值不可修改,常用于常量定义:

readonly MAX_CONNECTIONS=1000
readonly -p             # 列出所有只读变量
MAX_CONNECTIONS=2000    # 错误: bash: MAX_CONNECTIONS: readonly variable

重要细节

引号的区别

a=$HOME        # 变量 $HOME 展开为 /home/user
a="$HOME"      # 同上(推荐,语义清晰)
a='$HOME'      # 字面量字符串 "$HOME",变量不展开

declare -x vs export

两者功能等价,export 是 POSIX 标准,declare -x 是 Bash 扩展。推荐在脚本内用 declare 统一风格,交互式 Shell 用 export

子进程视角

a='local'
export b='global'
 
bash -c 'echo "a=$a b=$b"'    # 输出: a= b=global

环境变量(export)通过 fork()/exec() 时的环境块传递给子进程;非导出变量仅存在于当前 Shell 的内存中。

查看变量

set          # 查看所有变量(含环境变量)
env          # 仅查看环境变量
printenv     # 等同于 env
export -p    # 查看所有导出的变量
declare -p   # 查看所有变量及其属性

相关笔记