Терминальный текст становится невидимым после завершения подпроцесса - PullRequest
14 голосов
/ 27 июня 2011

После завершения подпроцесса ffmpeg терминал портится - напечатанные символы невидимы! Ввод все еще работает в том, что команды могут быть выполнены, но ввод с клавиатуры не выводится на терминал.

Выдача команды оболочки reset возвращает все в нормальное состояние (или !reset из ipython), поэтому в качестве обходного пути проблема вызывает os.system('reset') внутри скрипта.

Другие вещи, которые я пробовал: import curses; curses.initscr() до запуска подпроцесса и curses.endwin() после завершения, что несколько сработало, но сломало другие вещи. Другая, возможно, связанная с этим проблема заключается в том, что после порождения дочернего процесса интерактивный терминал становится запаздывающим и иногда не может захватить набранные символы.

Код для запуска процесса выглядит так:

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

А потом, чтобы остановить это:

proc.terminate()
proc.communicate()

Что здесь может пойти не так?

Ответы [ 3 ]

16 голосов
/ 12 июля 2011

Измените скрипт, чтобы proc.terminate() не использовался. Вы можете вежливо остановить подпроцесс ffmpeg с помощью

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

Это позволяет ffmpeg записать любые escape-последовательности, необходимые для восстановления терминала.


edit: обнаружен позже - еще один совет, чтобы заставить ffmpeg вести себя лучше с Popen, - предоставить ему subprocess.PIPE или open(os.devnull) в дескрипторе stdin. В противном случае он пытается получить входные данные от родительского stdin, что может вызвать странное поведение терминала. Работающий процесс ffmpeg прослушивает '?' и 'q' ввод на стандартный ввод.

2 голосов
/ 16 июля 2014

os.system('stty sane') работал для меня. Сбрасывает настройки, делая эхо невидимым.

2 голосов
/ 07 июля 2011

вы общаетесь с подпроцессом?в этом случае я бы использовал pexpect, что делает этот тип установки очень простым, возможно, вам нужно дождаться завершения команды?то есть

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

это то, что я использую в сценарии dvd2h264, который я написал некоторое время назад, с ним никогда не было проблем, но я не перенаправляю stdin / stderr в tmpfiles ..

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...