从init.d脚本执行时,Python Popen进程无法正常工作

时间:2015-01-13 08:01:16

标签: python raspberry-pi popen init.d

我有一个存储在/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)

/ EDIT

此时它会停止。我可以告诉你,因为它在这一步之前和之后写了一个调试文件,而第二个从未写过。

但事情是如果我在终端中执行

sudo sh /etc/init.d/begin start

然后" python3 script.py"执行完全没问题,包括Popen部分。

为什么会这样? THX

(init.d脚本)

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

#USER=pi
HOME=/home/pi

#export USER HOME
export HOME

case "$1" 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

1 个答案:

答案 0 :(得分:1)

子进程启动后,

Popen()会立即返回。它不等待它完成。您的脚本不太可能在Popen()上长时间阻止。

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

手动运行时看不到错误,因为环境不同:磁盘已挂载,音频服务正在运行,X已启动等 - 我不知道espeakaplay需要运行。

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

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

  

我可以看到问题是什么,而且是用强调词语传递一个参数(奇怪的是,当我从shell执行脚本时,情况并非如此)。我已经消除了重音,现在它可以正常工作了。

尝试指定utf-8语言环境。默认值是使用ascii编码的C语言环境,它不能直接表示突出的单词:

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

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