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
我将以下 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