Bash 无法识别 systemd 单元文件中是否存在右单引号

Bash won’t recognize existence of closing single quote in systemd unit file

我将以下 systemd 单元文件设置为同时自动更新所有 Arch Linux 和 AUR 包(当然使用 yay AUR 助手)同时还尝试临时添加(然后在完成后删除,原因很明显)一个 sudoers.d 条目来短暂地给任何人 sudo 访问 pacman 以便更新 AUR 包:

[Unit]
Description=Automatic Update
After=network-online.target

[Service]
Type=simple
SyslogIdentifier=autoupdate
ExecStartPre=/bin/bash -c 'echo \'nobody ALL= NOPASSWD: /usr/bin/pacman\' > /etc/sudoers.d/autoupdate'
ExecStart=/bin/bash -c \”XDG_CACHE_HOME=/var/tmp PWD=/var/tmp sudo -E -u nobody yay -Syuq --noconfirm --devel --timeupdate\”
ExecStartPost=/usr/bin/rm -f /etc/sudoers.d/autoupdate
KillMode=process
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target

问题是 bash 无法确认 ExecStartPre 行上结束单引号的存在:

nobody: -c: line 1: unexpected EOF while looking for matching `’`
nobody: -c: line 2: syntax error: unexpected end of file

这当然是尽管手动输入 sudo bash -c ‘echo nobody ALL\=NOPASSWD: /usr/bin/pacman > /etc/sudoers.d/autoupdate’ 到我的 shell 成功而没有发生意外。

是什么导致了这种差异?

事实证明,问题过于复杂的根源在于使用 ExecStartPost= 而不是 ExecStopPost=。一旦我将前者更改为后者,很久以前发布的单元文件的原始版本(简单得多)就可以完美地工作。

不管你为什么要使用 sudo 即使你是 root .. 并且不考虑您的代码..
请改用脚本

 ExecStartPre=/path/to/your/script prestart
 ExecStart=/path/to/your/script start
 ExecStartPost=/path/to/your/script poststart
    

你的脚本

#!/bin/bash
case  in
        prestart)  echo "nobody ALL= NOPASSWD: /usr/bin/pacman" > /etc/sudoers.d/autoupdate;;
        start)     XDG_CACHE_HOME=/var/tmp
                   PWD=/var/tmp
                   sudo -E -u nobody yay -Syuq --noconfirm --devel --timeupdate;;
        poststart) rm -f /etc/sudoers.d/autoupdate;;
esac