Popen.kill()失败了

时间:2015-06-14 20:26:25

标签: python raspberry-pi

更新2:所以我输出了stderr的输出,看起来当我包含shell = True时,我只是获取omx播放器的帮助文件(它列出了所有命令行开关等)。是否有可能shell = True可能无法与omxplayer很好地配合使用?

更新:之前我遇到过这个链接,但它失败了,所以我继续前进而没有深入挖掘。在Tshepang再次建议后,我进一步调查了它。我有两个问题,我希望第一个是由第二个引起的。第一个问题是,当我将shell = True作为arg包含时,视频永远不会播放。如果我不包括它,视频播放,但不会被杀死。更新了以下代码。

所以我正在尝试为我的覆盆子pi编写一个python应用程序,在循环播放视频(我遇到了Popen作为使用OMXplayer完成此操作的好方法)然后在键盘中断时,它会杀死该进程并打开另一个过程(播放不同的视频)。我最终的目标是能够使用vid1作为一种“屏幕保护程序”,并在用户与系统交互时使用vid2播放,但是现在我只是试图在键盘输入上杀死vid1并且在很难的时候运行它。我希望有人可以告诉我我的代码在哪里掉下来。

预告我对Python和基于Linux的系统一般都是新手,所以如果我这样做非常错误,请随意重定向我,但这似乎是实现这一目标的最快方式。

这是我的代码:

import subprocess
import os
import signal

vid1 = ['omxplayer', '--loop', '/home/pi/Vids/2779832.mp4']

while True:
    #vid = subprocess.Popen(['omxplayer', '--loop',     '/home/pi/Vids/2779832.mp4'], stdout=subprocess.PIPE, shell=True,     preexec_fn=os.setsid)
    vid = subprocess.Popen(vid1, stdout=subprocess.PIPE, preexec_fn=os.setsid)
    print 'SID is: ', preexec_fn
    #vid = subprocess.Popen(['omxplayer', '--loop',     '/home/pi/Vids/2779832.mp4'])
    id = raw_input()
    if not id:
        break
    os.killpg(vid.pid, signal.SIGTERM)
    print "your input: ", id
print "While loop has exited"

1 个答案:

答案 0 :(得分:0)

So I am trying to write a python app for my raspberry pi that plays a video on a loop (I came across Popen as a good way to accomplish this using OMXplayer) and then on keyboard interrupt, it kills that process and opens another process (playing a different video).

By default, SIGINT is propagated to all processes in the foreground process group, see "How Ctrl+C works". preexec_fn=os.setsid (or os.setpgrp) actually prevents it: use it only if you do not want omxplayer to receive Ctrl+C i.e., use it if you manually call os.killpg when you need to kill a process tree (assuming omxplayer children do not change their process group).

"keyboard interrupt" (sigint signal) is visible as KeyboardInterrupt exception in Python. Your code should catch it:

#!/usr/bin/env python
from subprocess import call, check_call

try:
   rc = call(['omxplayer', 'first file'])
except KeyboardInterrupt:
   check_call(['omxplayer', 'second file'])
else:
   if rc != 0:
      raise RuntimeError('omxplayer failed to play the first file, '
                         'return code: %d' % rc)

The above assumes that omxplayer exits on Ctrl+C.

You could see the help message due to several reasons e.g., omxplayer does not support --loop option (run it manually to check) or you mistakenly use shell=True and pass the command as a list: always pass the command as a single string if you need shell=True and in reverse: always (on POSIX) pass the command as a list of arguments if shell=False (default).