簡體   English   中英

殺死python ffmpeg子進程會破壞cli輸出

[英]Killing python ffmpeg subprocess breaks cli output

我正在嘗試使用子進程執行系統命令並讀取輸出。

但是,如果命令花費了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管道上打印所有內容。 這可能是原因嗎? 任何想法如何解決?

好。 您的代碼在我的Ubuntu服務器上肯定可以正常工作。

(我想這是Debian的近親或兄弟)

我增加了幾行,以便我可以測試您的代碼。

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(1)

    stderr = ''
    try:
        stdout, stderr = p.communicate()
        signal.alarm(0)
    except Alarm:
    print "Done!"
        try:
            os.kill(p.pid, signal.SIGKILL)
        except:
            pass

    return (stdout, stderr)

args = ('find', '/', '-name','*')
stdout = pexec(args)
print "----------------------result--------------------------"
print stdout
print "----------------------result--------------------------"

奇跡般有效。

如果此代碼在您的服務器上有效,我想問題實際上就在於

您嘗試檢索數據的命令行應用程序。

我也有同樣的問題。 我無法獲得運行中的FFmpeg來從python子<process>.kill()正常終止,因此我正在使用<process>.kill() 但是我認為這意味着FFmpeg無法正確還原tty的模式(如此處所述: https : //askubuntu.com/a/172747

您可以通過在bash提示符處運行reset恢復外殼,但這會清除屏幕,因此在繼續工作時看不到腳本的輸出。

更好的方法是運行stty echo ,以便在您的Shell會話中重新打開stty echo

對FFmpeg進行核對后,甚至可以在腳本中運行它。 我在做:

ffmpeg_popen.kill()
ffmpeg_popen.wait()
subprocess.call(["stty", "echo"])

這在bash作為shell的Ubuntu上對我有效。 YMMV,但希望對您有所幫助。 它聞起來很黑,但這是我找到的最好的解決方案。

我遇到了ffmpeg的類似問題。 看來,如果使用Popen.kill()將ffmpeg殺死,則無法正確關閉ffmpeg,也不會恢復終端上的回顯。

我們可以使用管道連接到stdin,然后像在cli會話中那樣寫q來關閉ffmpeg來解決此問題:

p = Popen(args, stdin=PIPE stdout=PIPE, stderr=PIPE)
p.stdin.write(b"q")

最好使用Popen.communicate以避免死鎖。 以下內容也將起作用:

p = Popen(args, stdin=PIPE stdout=PIPE, stderr=PIPE)
p.communicate(b'q')

但似乎甚至以下作品:

p = Popen(args, stdin=PIPE stdout=PIPE, stderr=PIPE)
p.kill()

我不確定是什么原因導致該ffmpeg干凈關閉,如果它具有輸入管道。 也許與最初導致此錯誤的原因有關?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM