变量、环境与 export¶
Shell 变量只存在于当前 Shell;执行 export 后,它才进入当前 Shell 的环境,并在创建子进程时传给子进程。
子进程不能反向修改父 Shell 环境。脚本直接执行与 source 的效果因此不同。
定义与引用¶
变量名区分大小写。Shell 自用变量通常使用小写,环境变量惯例使用大写,避免覆盖 PATH、HOME、IFS 等系统变量。
export¶
验证继承:
local_only=one
export inherited=two
bash -c 'printf "local=%s inherited=%s\n" "$local_only" "$inherited"'
只给一条命令设置环境:
这不会永久修改当前 Shell 的变量,适合测试一次命令。
source 与执行脚本¶
不要 source 不可信脚本,因为其中任何命令都会在当前 Shell 权限下执行。
PATH¶
把新目录放前面会覆盖同名系统命令;放后面则只作为补充。不要写:
这会丢失 /usr/bin 等原路径。也不要把当前目录 . 放在 PATH 前面,防止执行恶意同名文件。
常见启动文件¶
| 场景 | Bash 常见文件 |
|---|---|
| 登录 Shell | /etc/profile、~/.bash_profile 等 |
| 交互非登录 Shell | ~/.bashrc |
| systemd 服务 | Unit 的 Environment=/EnvironmentFile=,通常不读取用户 bashrc |
| cron | 环境非常精简,应显式 PATH 和变量 |
| Docker/Compose | environment、env_file,与宿主 Shell 插值要区分 |
SSH、sudo、systemd、cron、容器各有不同环境继承规则。终端中 export 成功,不代表 systemd 服务能看到。
查看环境¶
env | sort
printenv PATH
export -p
declare -p APP_ENV
# Linux 查看进程环境,内容可能包含 Secret
tr '\0' '\n' < /proc/<pid>/environ
读取进程环境前注意权限和敏感信息,不要把完整输出发到工单。
参数展开¶
value=${APP_ENV:-development} # 未设置或为空时用默认值
value=${APP_ENV:=development} # 使用默认值并赋值
: "${DB_HOST:?DB_HOST is required}" # 未设置或为空则报错退出
length=${#APP_ENV}
file=${path##*/} # 去掉最长目录前缀
${var:-default} 不会把默认值写回变量;${var:=default} 会。脚本处理必填参数时使用 :? 比运行到中途才报空地址更安全。
Secret 边界¶
环境变量可能出现在 /proc、进程转储、调试信息、容器 inspect 或 CI 日志。密码和 Token 不要写进 Shell 历史、命令行参数或仓库;优先使用权限受控文件、Secret 管理系统和短期凭据。