我正在尝试使用子进程执行系统命令并读取输出。
但是如果命令需要超过 10 秒,我想杀死子进程。
我已经尝试以多种方式做到这一点。
我最后一次尝试的灵感来自这篇文章:https ://stackoverflow.com/a/3326559/969208
例子:
import os
import signal
from subprocess import Popen, PIPE
class Alarm(Exception):
pass
def alarm_handler(signum, frame):
raise Alarm
def pexec(args):
p = Popen(args, stdout=PIPE, stderr=PIPE)
signal.signal(signal.SIGALRM, alarm_handler)
signal.alarm(10)
stdout = stderr = ''
try:
stdout, stderr = p.communicate()
signal.alarm(0)
except Alarm:
try:
os.kill(p.pid, signal.SIGKILL)
except:
pass
return (stdout, stderr)
问题是:程序退出后,cli 中不会显示任何字符,直到我点击返回。并且点击返回不会给我一个新的线路。
我想这与 stdout 和 stderr 管道有关。
我已经尝试从管道中冲洗和读取(p.stdout.flush())
我也尝试过不同的 Popen 参数,但可能错过了一些东西。只是想我会在这里保持简单。
我在 Debian 服务器上运行它。
我在这里错过了什么吗?
编辑:
似乎只有在终止正在进行的 ffmpeg 进程时才会出现这种情况。如果 ffmpeg 进程在 10 秒前正常退出,则完全没有问题。
我尝试执行几个不同的命令,这些命令需要超过 10 秒,一个打印输出,一个不打印输出,还有一个 ffmpeg 命令来检查文件的完整性。
args = ['sleep', '12s'] # Works fine
args = ['ls', '-R', '/var'] # Works fine, prints lots for a long time
args = ['ffmpeg', '-v', '1', '-i', 'large_file.mov','-f', 'null', '-'] # Breaks cli output
我相信 ffmpeg 使用 \r 打印并在 strerr 管道上打印所有内容。这可能是原因吗?任何想法如何解决它?