这$(ls -d...)
在 systemd 单元文件中不起作用:
[Service]
Type=forking
Environment="ORACLE_HOME=$(ls -d /usr/lib/oracle/*/client64 | sort -rV | head -n1)"
Environment="TNS_ADMIN=$(ls -d /usr/lib/oracle/*/client64/lib/network/admin | sort -rV | head -n1)"
我想避免对 Oracle 客户端版本(目前为 19.19)进行硬编码,以简化更新。当我安装新的 Oracle 客户端时,我不想修改 systemd 单元文件。
我怎样才能做到这一点?如果重要的话我使用 RHEL9。
最常见的方法:
使用
EnvironmentFile=
动态生成的,例如通过调用简单脚本的 ExecStartPre= 。当前的 systemd 版本将在每次执行之前重新读取 EnvironmentFile 以允许其工作。(/run 是存放临时文件的好位置。)这是最简单的方法,因为脚本只需要写出这些
KEY="value"
行。使用 systemd生成器,每次(重新)加载配置时,它都会在 /run/systemd 动态写入单元文件。生成器可以是 shell 脚本,只要它仅限于本地文件系统访问。
发电机可以放置在
/etc/systemd/system-generators/
;它们将在每次启动和每次“systemctl daemon-reload”期间运行,获取输出路径为$1
. 它们实际上会在任何单元启动之前运行,因此它们不能期望网络或其他任何东西都会启动。这是最灵活的方法,因为任何单位选项都可以动态指定 - 不仅是环境,还包括其他内容,例如WorkingDirectory=。(生成器不需要创建整个单元;它可以通过创建
$1/oracle.service.d/environ.conf
或类似的方式以通常的方式扩展现有单元。)其他方法:
[email protected]
使用一个实例化的服务单元%i
来填充版本。您仍然需要禁用“oracle@old”并启用“oracle@new”,但它可以节省您打开文本编辑器的时间。(而且它还可以通过启动正确的单元轻松快速回滚到旧版本。)我认为您可以拥有一个Alias=oracle.service
,以便启用实例会自动将其映射到较短的名称。使用包装 shell 脚本来设置变量并
exec
保存实际程序。是的,这exec
很重要。(另外,使用 SyslogIdentifier= 来防止脚本的名称显示 Journalctl 输出。)通常不鼓励使用包装器脚本,但这通常是因为它们执行的操作可以通过 .service 轻松完成,但这里的情况并非 100%。避免
systemctl set-environment
,因为它是全局的 - 变量将可供该点之后启动的所有服务使用,无论它们是否想要它们。