Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Terminal text becomes invisible after terminating subprocess

After terminating an ffmpeg subprocess, the terminal gets messed up - typed characters are invisible! The input still works in that commands can be executed, but keyboard input is not echoed to the terminal.

Issuing shell command reset puts everything back to normal (or !reset from within ipython), so a workaround the issue is calling os.system('reset') inside the script.

Other things I've tried: import curses; curses.initscr() before spawning the subprocess and curses.endwin() after termination, which worked somewhat but broke other stuff. Another possibly related issue is that after spawning the child process, the interactive terminal becomes laggy and sometimes fails to capture typed characters.

The code to spawn the process looks like:

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

And later to stop it:

proc.terminate()
proc.communicate()

What could be going wrong here?

like image 484
wim Avatar asked Jun 27 '11 03:06

wim


4 Answers

Change the script so that proc.terminate() is not used. You can stop an ffmpeg subprocess more politely with

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

This allows ffmpeg the chance to write whatever escape sequences it needs to restore the terminal.


edit: discovered later- another tip to make ffmpeg behave better with Popen is to provide it a subprocess.PIPE or open(os.devnull) in the stdin handle. Otherwise, it seems to try to get input from the parent's stdin which can cause weird terminal behaviour. A running ffmpeg process is listening for '?' and 'q' input on stdin.

like image 102
wim Avatar answered Nov 19 '22 15:11

wim


As stated in this answer, ffmpeg expects data from stdin. You can run ffmpeg with the -nostdin flag and it will keep your terminal from hiding keystrokes.

like image 44
Ian Hunter Avatar answered Nov 19 '22 15:11

Ian Hunter


do you communicate with the subprocess? in that case i would use pexpect which makes that type of setup very simple, perhaps you must wait for the command to finish? i.e.

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

that's what i use on a dvd2h264 script i wrote a while back, never had any problems with it, but i don't redirect stdin/stderr to tmpfiles..

like image 2
bjarneh Avatar answered Nov 19 '22 15:11

bjarneh


os.system('stty sane') worked for me. It reset settings making echo invisible.

like image 2
Quentin Engles Avatar answered Nov 19 '22 14:11

Quentin Engles