我希望能够从 Node-RED 中重新启动 ConnMan。该服务由其自己的用户运行nodered
。
当我以用户身份 SSH 进入设备nodered
并键入
nodered@pi:~$ sudo /etc/init.d/connman restart
这样可行。
但是,当我调用visudo
并添加以下行时:
nodered ALL = (root) NOPASSWD: /etc/init.d/connman restart
执行命令时它给我以下错误:
nodered@pi:~$ /etc/init.d/connman restart
Restarting Connection Manager
/etc/init.d/connman: line 47: kill: (28874) - Operation not permitted
失败的行/etc/init.d/connman
是:
do_stop() {
# kill the script monitoring execution
if [ "X${pid=$(pidof -x /usr/sbin/connmand-watch.sh)}" != "X" ]; then
kill $pid
答案1
如果服务及其观察程序都以用户身份运行nodered
并且您以同一用户身份登录,那么您sudo
根本不需要:进程的所有者将始终有权终止它,即使kill -9
有必要也是如此。
这sudoers
行:
nodered ALL = (root) NOPASSWD: /etc/init.d/connman restart
授予nodered
用户以 root 身份运行命令的能力/etc/init.d/connman restart
。如果脚本或服务本身不能确保服务及其观察程序都以用户身份启动nodered
,则运行此脚本sudo
可能会产生意外的副作用,connmand-watch.sh
即以 root 拥有的进程重新启动服务和/或脚本。当心。
使用kill -0
,您可以测试是否可以杀死进程,而无需真正发送任何信号。您可以在脚本的开头执行类似的操作/etc/init.d/connman
:
if [ $(whoami) != "root" ]; then
watcherpid=$(pidof -x /usr/sbin/connmand-watch.sh)
if [ "" != "$watcherpid" ] && ! kill -0 "$watcherpid" 2>/dev/null; then
# Watcher exists but cannot be signaled so it runs as some other user.
# Attempt to re-execute this script with root powers.
exec sudo /etc/init.d/connman "$@"
# If we reach this line, we could not exec sudo. That's bad.
exit 1
fi
fi
使用exec sudo /etc/init.d/connman "$@"
,脚本将通过 sudo 重新运行。由于exec
,脚本的常规非特权副本的执行将立即结束,并且sudo
ed 版本将使用与原始调用相同的命令行参数来替换它。
如果无法找到观察程序进程,或者脚本已经以 root 身份运行,则此测试将失败,无需执行任何操作。
注意:如果脚本尝试重新运行自身sudo
并且尝试失败,则脚本将停止而不执行任何操作。