Python 从 init.d 脚本执行时,Popen 进程不工作

Python Popen process not working when it is executed from init.d script

我有一个脚本存储在 /etc/init.d 中,在启动时执行时可以正常工作。由于我没有导出 USER,因此它应该以 root 身份执行所有操作(如果我没记错的话)。

然后,它执行python3 script.py 在此脚本中,一切正常,直到达到

espeak_process = Popen(["espeak", "-ves", "-s100", msg, "--stdout"], stdout=subprocess.PIPE)
aplay_process = Popen(["aplay", "-D", "sysdefault"], stdin=espeak_process.stdout, stdout=subprocess.PIPE)

编辑:更改了此代码,但创建的文件为空

def log_uncaught_exceptions(ex_cls, ex, tb):
    f = open('/home/pi/debug_err.txt', 'w')
    f.write('hi ')
    f.write(ex_cls+' '+ex+' '+tb)
    f.close()

sys.excepthook = log_uncaught_exceptions
espeak_process = Popen(["espeak", "-ves", "-s100", msg, "--stdout"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

/编辑

此时它停止了。我可以看出,因为它在这一步之前和之后都写了一个调试文件,而第二个文件从来没有写过。

问题是,如果我在终端中执行

sudo sh /etc/init.d/begin start

然后"python3 script.py"就完全可以执行了,包括Popen部分。

为什么会这样? 谢谢

(init.d 脚本)

#! /bin/sh
# /etc/init.d/begin 

#USER=pi
HOME=/home/pi

#export USER HOME
export HOME

case "" in
 start)
  if [ -f "/home/pi/begin.pid" ];
  then
    kill -9 $(cat /home/pi/begin.pid)
    rm -f /home/pi/begin.pid
  fi
  python3 /home/pi/script.py &
  ;;

 stop)
  kill -9 $(cat /home/pi/begin.pid)
  rm -f /home/pi/begin.pid
  ;;

 *)
  echo "Usage: /etc/init.d/begin {start|stop}"
  exit 1
  ;;
esac

exit 0

Popen() returns 子进程一启动。它不会等待它完成。您的脚本不太可能在 Popen().

上长时间阻塞

一个可能的解释是您的脚本在尝试启动 espeakaplay 进程时引发异常并终止——这就是您在日志文件中看不到第二条记录的原因.捕获并记录所有错误,例如,设置 sys.excepthook.

手动 运行ning 时您看不到错误,因为环境不同:磁盘已挂载,音频服务 运行ning,X 已启动,等等 -- 我没有不知道 espeakaplay 对 运行 的要求。

作为替代方案,将所有输出保存到文件中:

# python3 /home/pi/script.py </dev/null >/home/pi/script.out 2>/home/pi/script.err &

I can see what's the problem, and it was to pass an argument with accentuated words (strange that it wasn't the case when I executed the script from the shell). I've eliminated the accents and now it works ok.

尝试指定 utf-8 语言环境。默认是C语言环境,使用ascii编码,不能直接表示重读词:

# LANG=C.UTF-8 python3 ...

如果 locale -a 命令的输出中没有 C.UTF-8 语言环境,则从列表中选择任何其他 utf-8 语言环境。