首页/系统/Linux 运维命令速查/服务环境变量注入(EnvironmentFile)
systemd 与服务42 条

服务环境变量注入(EnvironmentFile)

systemd 服务环境变量三种写法:单元内联 Environment=、外部 EnvironmentFile=、以及 ExecStart 里显式 env;敏感配置放文件并用 600 权限。

Linux 运维命令速查系统更新于 2026-10-13

环境变量注入是什么

systemd 启动服务时并不经过交互式 shell,所以 `export` 与环境脚本都不会自动生效。变量要通过单元里的 Environment= 内联声明,或 EnvironmentFile= 指定一个 KEY=VALUE 文件注入,也可以直接在 ExecStart 前面用 env 命令显式设置。这三种方式决定了服务进程能看到什么环境,是「本地跑得通、装上服务就报找不到配置」类问题的第一现场。

基本信息

适用平台Linux(systemd)
写在哪个段[Service] 段
三种写法Environment=KEY=VALUE 内联;EnvironmentFile=/path 文件注入;ExecStart=/usr/bin/env KEY=VALUE 命令
文件格式每行 KEY=VALUE,无 export、无引号、不支持行内注释、不做 shell 展开
可选文件路径前加 - 表示文件不存在时忽略,不报错
权限要求env 文件常含凭据,建议 600 且属主 root;单元文件本身通常 644

典型使用场景

  • 数据库连接串、密钥等敏感配置从单元文件里剥离,放独立文件便于单独控制权限
  • 同一程序部署多实例:用不同 EnvironmentFile 区分端口、日志路径与租户
  • 与环境变量式配置的应用对接(Spring Boot 的 SERVER_PORT、Node 的 NODE_ENV)
  • 灰度与回滚:只切 env 文件内容,不改单元、不重装包
  • 区分可选配置:用 - 前缀让可选文件缺失时不影响启动

单元中的三种写法

单元中的三种写法
[Service]
EnvironmentFile=/etc/myapp/env              # 必选文件,缺失则启动失败
EnvironmentFile=-/etc/myapp/env.optional    # 可选文件,缺失时忽略
Environment=LOG_LEVEL=info                  # 内联声明,简单值用这个
ExecStart=/usr/bin/env APP_MODE=prod /opt/app/bin/app   # 只对这一次执行生效

env 文件格式

env 文件格式
# /etc/myapp/env  —— KEY=VALUE,每行一条,没有 export
db_host=127.0.0.1
db_port=5432
db_user=app
# 值里不要出现行内注释符号,它会被当成值的一部分
timeout=30

三种注入方式对比

方式绑定关系适用与注意
Environment=写死在单元里值简单、不敏感时用;会出现在 systemctl show 输出中
EnvironmentFile=指向外部文件适合敏感值与多环境差异;改文件只需 restart 服务
ExecStart 前置 env只影响该条命令适合一次性覆盖;多个 ExecStart 要各自写
$VAR 与 ${VAR}在 ExecStart 等指令里引用注入的变量变量不存在时展开为空,注意别把路径写空
EnvironmentFile 由 root 读取后注入进程:文件权限设 600、属主 root,否则任何本地用户都能读到数据库口令。另外注入后的值会出现在 systemctl show 的输出里,敏感项要考虑这个展示面。
单元里用 Environment= 与多个 EnvironmentFile= 时按出现顺序生效,后面的覆盖前面的,所以可以把公共默认值放前面、环境专属覆盖放后面。改 env 文件内容后只需 restart 服务;只有改单元文件本身才需要先 daemon-reload。

易错点

  • env 文件里写了 export 或给值加引号,会被当作值的一部分,导致变量值错误(如 export 被当成变量名)
  • systemd 的 env 文件不是 shell:不支持行内注释,值里出现的 # 会原样成为值的一部分
  • EnvironmentFile 的路径本身不支持通配符与变量展开,写错路径且没加 - 前缀会导致服务直接启动失败
  • EnvironmentFile 变更不需要 daemon-reload,但改了单元文件里的 Environment= 就必须 daemon-reload,否则重启也用的是旧定义
  • 变量未定义时在 ExecStart 里展开为空字符串,可能把 --config 参数变成空值,脚本类启动命令要注意兜底

数据来源与参考

  • man 5 systemd.exec(Environment/EnvironmentFile)

相关工具

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌