Systemd ExecStart 参数在脚本内部不可访问

Systemd ExecStart 参数在脚本内部不可访问

我遇到了一个非常奇怪的情况。

我有一个 systemd 单元

[Unit]
Description=Nightly snapshot backup job for [%i] volume

[Service]
Type=simple
KillMode=process
EnvironmentFile=/etc/systemd/schedule-backup_%i.conf
ExecStart=/usr/local/bin/backup.sh -s '$SOURCE' -b '$BACKUP' -t '$TITLE' -l 'backup_%i.log'

当我使用服务实例执行该操作时: sudo systemctl启动[电子邮件保护]

backup.sh 脚本根本没有接收最后一个参数。它应该接收“backup_projects.log”

我正在读取参数

while getopts s:b:t:l: flag
do
    case "${flag}" in
        s) source_path_root="${OPTARG}";;
        b) backup_path_root="${OPTARG}";;
        t) email_title="${OPTARG}";;
        l) log_name="${OPTARG}";;
    esac
done

当我检查服务日志时,似乎该脚本是使用适当的参数调用的:

systemctl -l status [email protected] -n50
[email protected] - Nightly snapshot backup job for [projects] volume
     Loaded: loaded (/etc/systemd/system/[email protected]; static)
     Active: inactive (dead) since Tue 2021-12-14 12:47:01 EET; 16min ago
TriggeredBy: ● schedule-backup_projects.timer
    Process: 8161 ExecStart=/usr/local/bin/backup.sh -s $SOURCE -b $BACKUP -t $TITLE -l backup_projects.log (code=exited, status=0/SUCCESS)
   Main PID: 8161 (code=exited, status=0/SUCCESS)
        CPU: 3.122s

Dec 14 12:46:56 fallen-robot systemd[1]: Started Nightly snapshot backup job for [projects] volume.
Dec 14 12:46:56 fallen-robot backup.sh[8161]: /usr/local/bin/backup.sh: line 37: /var/log/: Is a directory
Dec 14 12:46:56 fallen-robot backup.sh[8161]: Log file set to /var/log/

当我从控制台执行相同的脚本时,参数被正确接受。我做错了什么?

编辑:似乎只要我将 -l 参数放在开头而不是结尾,它就会起作用。可能是 getopts 出了问题。我会接受任何能解释这一点的人的回答

答案1

我发现问题在于,systemd 对来自 EnvironmentFiles 的变量有自己的规则

https://fedoraproject.org/wiki/Packaging:Systemd#EnvironmentFiles_and_support_for_.2Fetc.2Fsysconfig_files

它说

然后,您可以在 ExecStart= 行(和相关行)中使用 ${FOOBAR} 和 $FOOBAR 引用 /etc/sysconfig/httpd 文件中设置的变量。 (${FOOBAR} 将变量扩展为一个单词, $FOOBAR 将变量值在空格处拆分为多个单词)

在我把我的线路改为

ExecStart=/usr/local/bin/backup.sh -s ${SOURCE} -b ${BACKUP} -t ${TITLE} -l backup_%i.log

我的问题解决了,包括一个包含空格的 TITLE。没有 {} TITLE 被扩展为 3 个单词,并且由于第二个和第三个在 getopts 中没有出现“-”,它将停止进一步的参数处理,从而忽略 -l backup_%i.log 部分

getopts 实现了标准选项处理,这意味着当它看到一个不是选项的参数时,它会停止寻找选项……

礼貌https://unix.stackexchange.com/a/666748/499351

相关内容