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()
.
上长时间阻塞
一个可能的解释是您的脚本在尝试启动 espeak
或 aplay
进程时引发异常并终止——这就是您在日志文件中看不到第二条记录的原因.捕获并记录所有错误,例如,设置 sys.excepthook
.
手动 运行ning 时您看不到错误,因为环境不同:磁盘已挂载,音频服务 运行ning,X 已启动,等等 -- 我没有不知道 espeak
、aplay
对 运行 的要求。
作为替代方案,将所有输出保存到文件中:
# 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 语言环境。
我有一个脚本存储在 /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()
.
一个可能的解释是您的脚本在尝试启动 espeak
或 aplay
进程时引发异常并终止——这就是您在日志文件中看不到第二条记录的原因.捕获并记录所有错误,例如,设置 sys.excepthook
.
手动 运行ning 时您看不到错误,因为环境不同:磁盘已挂载,音频服务 运行ning,X 已启动,等等 -- 我没有不知道 espeak
、aplay
对 运行 的要求。
作为替代方案,将所有输出保存到文件中:
# 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 语言环境。