CentOS7 Linux服务单元文件如何从外部配置文件读取变量值
CentOS7 systemd服务从外部配置文件读取参数传给Shell脚本的落地方法
方案一:使用systemd原生EnvironmentFile加载(优先推荐)
这是systemd内置的配置加载能力,没有额外的子进程开销,运行稳定性最高。
- 在服务单元文件(通常存放在
/etc/systemd/system/下对应服务的.service文件)的[Service]配置块中,新增一行指定外部配置文件的绝对路径:EnvironmentFile=/etc/myapp/service_config.txt - 修改原有的
ExecStart配置项,把硬编码的var1、var2参数替换为对配置内变量的引用,记得给变量加双引号,防止参数值带空格时被shell错误拆分:ExecStart=/opt/your/path/run.sh "${var1}" "${var2}"
该方案的适配要求
- 原生
EnvironmentFile要求配置文件格式为每行严格按照KEY=value书写,等号两侧不能有多余空格,否则systemd会把变量名、值附带空格导致解析失败。对应的service_config.txt要调整为如下格式:var1=value1 var2=value2 - 改完服务文件后必须执行
systemctl daemon-reload重载systemd配置,不然修改不会生效。 - 要保证服务运行的用户身份对
service_config.txt有读权限,避免启动时出现权限拒绝报错。
方案二:直接在启动命令中解析原有格式的配置文件
如果不想调整现有service_config.txt的格式(保留原有的var1 = value1这种等号两侧带空格的写法),可以直接在启动流程里嵌入解析逻辑,不依赖systemd的配置解析能力:
- 服务文件里不用加
EnvironmentFile,直接把ExecStart替换为如下形式:ExecStart=/bin/bash -c ' # 提取配置里的var1、var2,自动去掉等号两侧的多余空格 eval $(awk -F= "/^[[:space:]]*(var1|var2)[[:space:]]*=/ { gsub(/^[[:space:]]+|[[:space:]]+$/, \"\", \$1); gsub(/^[[:space:]]+|[[:space:]]+$/, \"\", \$2); print \$1"=\""\$2"\"" }" /etc/myapp/service_config.txt) # 用exec替换当前bash进程,让systemd能正确跟踪脚本的主PID exec /opt/your/path/run.sh "$var1" "$var2" '
该方案的注意事项
- 一定要加
exec关键字,否则当前bash进程会作为父进程常驻,实际运行的脚本会变成子进程,遇到服务停止操作时可能出现进程残留杀不干净的问题。 - 不要在这个启动命令里写太复杂的多层管道逻辑,一旦某一环解析出错,systemd会因为检测到非零退出码触发服务反复重启。
- 如果配置文件里的参数值包含特殊字符,要做好转义避免解析错误。
内容的提问来源于stack exchange,提问作者pabitra dalei
相关产品推荐
相关产品推荐

