终端文本在终止子进程后变得不可见

21 投票
6 回答
5901 浏览
提问于 2025-04-16 20:21

在结束一个 ffmpeg 子进程后,终端变得很混乱——你输入的字符看不见了!虽然你仍然可以输入命令并执行它们,但键盘输入不会在终端上显示出来。

输入命令 reset 可以把一切恢复正常(或者在 ipython 中输入 !reset),所以解决这个问题的一个方法是在脚本中调用 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()

这里可能出了什么问题呢?

6 个回答

4

os.system('stty sane') 对我来说有效。它重置了一些设置,让屏幕上的输入变得不可见。

9

正如这个回答中提到的,ffmpeg这个工具需要从标准输入(stdin)获取数据。你可以使用-nostdin这个选项来运行ffmpeg,这样就可以让你的终端不再隐藏你输入的按键。

24

把脚本改一下,不要用 proc.terminate()。你可以用更温和的方式来停止 ffmpeg 的子进程,方法是:

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

这样做可以让 ffmpeg 有机会写入它需要的任何转义序列,以恢复终端的正常状态。


补充:后来发现的另一个小技巧是,给 ffmpeg 提供一个 subprocess.PIPE 或者 open(os.devnull) 作为 stdin 的处理方式,这样可以让 ffmpeg 更好地与 Popen 配合。否则,它会试图从父进程的标准输入获取信息,这可能会导致终端出现奇怪的行为。正在运行的 ffmpeg 进程会在标准输入上监听 '?' 和 'q' 的输入。

撰写回答