21 Stimmen

Terminaltext wird nach Beendigung des Unterprozesses unsichtbar

Nach Beendigung eines ffmpeg Subprozess, gerät das Terminal durcheinander - getippte Zeichen sind unsichtbar! Die Eingabe funktioniert zwar noch, da Befehle ausgeführt werden können, aber die Tastatureingabe wird nicht an das Terminal zurückgesendet.

Shell-Befehl ausgeben reset setzt alles wieder in den Normalzustand zurück (oder !reset von ipython aus), so dass ein Workaround das Problem durch den Aufruf von os.system('reset') innerhalb des Skripts.

Andere Dinge, die ich ausprobiert habe: import curses; curses.initscr() bevor der Unterprozess gestartet wird und curses.endwin() nach der Beendigung, was zwar einigermaßen funktionierte, aber andere Dinge kaputt machte. Ein weiteres Problem, das möglicherweise damit zusammenhängt, ist, dass das interaktive Terminal nach dem Starten des Kindprozesses verzögert wird und manchmal die eingegebenen Zeichen nicht erfasst.

Der Code zum Starten des Prozesses sieht folgendermaßen aus:

with open('/tmp/stdout.log', 'w') as o:
    with open('/tmp/stderr.log', 'w') as e:
        proc = subprocess.Popen([args], stdout=o, stderr=e)

Und später, um sie zu stoppen:

proc.terminate()
proc.communicate()

Was könnte hier schiefgehen?

24voto

wim Punkte 297608

Ändern Sie das Skript so, dass proc.terminate() nicht verwendet wird. Sie können eine ffmpeg Unterprozess höflicher mit

  proc.send_signal(signal.SIGINT)
  proc.wait()

Dies gibt ffmpeg die Möglichkeit, alle Escape-Sequenzen zu schreiben, die es braucht, um das Terminal wiederherzustellen.


bearbeiten: Später entdeckt - ein weiterer Tipp zur Herstellung ffmpeg verhalten sich besser mit Popen ist es, ihm eine subprocess.PIPE o open(os.devnull) en el stdin Griff. Andernfalls scheint er zu versuchen, Eingaben von stdin des Elternprozesses zu erhalten, was zu einem merkwürdigen Verhalten des Terminals führen kann. Ein laufender ffmpeg-Prozess wartet auf '?' und 'q' Eingaben auf stdin.

9voto

Ian Hunter Punkte 8903

Wie in diese Antwort ffmpeg erwartet Daten von stdin. Sie können ffmpeg mit der Option -nostdin Flagge und verhindert, dass Ihr Terminal Tastatureingaben versteckt.

4voto

Quentin Engles Punkte 2590

os.system('stty sane') hat für mich funktioniert. Es hat die Einstellungen zurückgesetzt und das Echo unsichtbar gemacht.

2voto

bjarneh Punkte 598

Kommunizieren Sie mit dem Unterprozess? in diesem Fall würde ich pexpect verwenden, die diese Art von Setup sehr einfach macht, vielleicht müssen Sie warten, bis der Befehl beendet ist? d.h..

 p = subprocess.Popen(argv, stdout=o, stderr=e)
 p.wait()
 if p.returncode != 0:
      print("problems")

das ist, was ich in einem dvd2h264-Skript verwende, das ich vor einer Weile geschrieben habe, ich hatte nie Probleme damit, aber ich leite stdin/stderr nicht nach tmpfiles um.

0voto

ruanhao Punkte 4433

Wie wäre es damit:

 try:
     p = subprocess.Popen(argv, stdout=o, stderr=e)
 except KeyboardInterrupt:
     p.send_signal(signal.SIGINT)
     p.wait()

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X