让我们来看看这个。在当用户pi直接执行Python脚本时,一切正常。

当用户pi执行shell脚本包装器时,一切都按它应该的方式执行。(我不知道为什么要添加额外的复杂性层,您可以在Python脚本本身内完成所有这些。Linux的第一条规则-K.I.S.S.,Python的第三条禅-简单胜于复杂)

这说明脚本本身并没有什么根本性的错误,它们是有效的。但你确实有一个权限错误,只是不在你想的地方。还有另一个脚本,您只能顺便引用它—位于/etc/init.d/motion的运动服务脚本

在那里你会发现:restart)

$0 restart-motion

;;

它指向:

^{pr2}$

参考文献:start)

if check_daemon_enabled ; then
if ! [ -d /var/run/motion ]; then
mkdir /var/run/motion
fi
chown motion:motion /var/run/motion
log_daemon_msg "Starting $DESC" "$NAME"
if start-stop-daemon start oknodo exec $DAEMON -b chuid motion ; then
log_end_msg 0
else
log_end_msg 1
RET=1
fi
fi
;;

具体来说,我们关注的是:if start-stop-daemon start oknodo exec $DAEMON -b chuid motion ; then

在用户启动进程前停止进程。在本例中,进程所有者是“运动”用户。为了将来参考,另一种常用方法是在应用程序配置文件的变量和“chuid$”中设置用户。在

如果可以启动服务,获取此信息的一个简单方法是检查正在运行的进程的所有者,但是您应该知道在您的发行版中,当您无法启动服务时,应该在哪里查找各种servicemanager脚本(init/upstart/systemd)。在

我们知道你的脚本在你执行的时候是有效的,我们知道运动用户能够执行你的shell脚本,我们知道运动用户有权执行Python脚本。所以Python脚本本身肯定有什么东西在执行时失败了。在

最突出的一点是:os.system("sudo aplay /home/pi/detect/bark.wav")

作为用户动作,您正在尝试sudo这个命令。运动用户有sudo provides吗?在$ sudo -n -l -U motion

User motion is not allowed to run sudo on nagiospi.

你的权限有问题。在

所以有两种方法,给运动用户sudo播放音频文件的权限(坏的,见下文),或者找到一种不使用sudo播放文件的方法-如果aplay需要root,我会寻找Python库或用户可访问的实用程序。在

一些有用的建议:正如slugonamismission所评论的那样,让可执行的世界变得可写是糟糕的做法,我会说,世界读/写/可执行文件可能不应该在你的主目录中,把服务脚本所需的文件添加到列表中。

为什么要用shell脚本执行Python脚本来执行shell命令-选择一个脚本平台并坚持下去。不要把事情过度复杂化,我们所做的一切都足够神奇到规范。

授予sudo特权应该是您绝对不会尝试的事情。你永远不应该以root用户的身份运行守护进程,除非你绝对地、肯定地不能以其他方式运行它,而且即使这样,我也会开始寻找完全不同的解决方案。当谈论匿名访问服务时,这是一条绝对牢不可破的规则。