我有一个以非root 用户身份运行的nodejs 进程(并且需要这样做是有原因的),但它有一个依赖项,需要root 访问权限才能访问raspberry pi gpio 中断。所以解决方案是我gpio
在 rpi 上有一个组,其中包含用于运行节点的 sudoers 条目。然后我用服务单元文件启动这个脚本,它工作正常
[Unit]
Description=switches16-mcp230xx-dSxJM-interrupt Device Starter Service
After=network-online.target
[Service]
Environment=UCI_ENV=pro
ExecStart=/usr/bin/sudo /usr/bin/node -r esm /opt/light/switches16-mcp230xx-dSxJM-interrupt/index.js
Restart=on-failure
WorkingDirectory=/opt/light/switches16-mcp230xx-dSxJM-interrupt
[Install]
WantedBy=default.target
问题出现在重新启动(或失败重新启动)时。该进程需要被终止,但它是作为 sudo 启动的,所以毫不奇怪,它也必须使用 sudo 终止。
Mar 12 19:43:12 switches systemd[1289]: switches16-mcp230xx-dSxJM-interrupt.service: Failed to kill main process 11222 (sudo), ignoring: Operation not permitted
Mar 12 19:43:12 switches systemd[1289]: switches16-mcp230xx-dSxJM-interrupt.service: Killing process 11223 (node) with signal SIGKILL.
Mar 12 19:43:12 switches systemd[1289]: switches16-mcp230xx-dSxJM-interrupt.service: Failed to kill control group /user.slice/user-1000.slice/[email protected]/switches16-mcp230xx-dSxJM-
因此,由于单元文件是作为非 root 用户启动的,所以它会作为用户杀死,所以我假设我必须在启动它时故意使用 sudo 杀死该进程。所以我添加了这个。
ExecReload=/usr/bin/sudo /bin/kill -HUP $MAINPID
但得到了同样的错误。即使我的 sudoers.d 文件有
%gpio ALL=NOPASSWD: /usr/bin/node
%gpio ALL=NOPASSWD: /bin/kill
我一定在这里遗漏了一些东西,但我无法指出它。
这是单元文件产生的进程,必须在重新启动之前终止
root 11093 0.0 0.3 8468 2920 ? Ss 18:01 0:00 \_ /usr/bin/sudo /usr/bin/node -r esm /opt/light/switches16-mcp230xx-dSxJM-interrupt/index.js
root 11094 6.7 4.8 142820 45788 ? SLl 18:01 6:52 \_ /usr/bin/node -r esm /opt/light/switches16-mcp230xx-dSxJM-interrupt/index.js
有什么建议么?
让我重申一下,我无法以 root 身份运行此服务,因此没有必要提出这样的建议,因为这显然是一个简单的答案。我正在部署此代码并通过 ssh 启动,无需 root 访问密钥,因此以无密码 sudo 的用户身份运行是我唯一的选择。如果我的代码中没有这种特定的硬件(根)依赖性,我根本不会遇到这个问题。