curses.wrapper()在后台/前景序列之后搞乱终端

时间:2015-07-15 20:28:04

标签: python ncurses curses python-curses

我正在调查curses.wrapper无法正常恢复终端的错误。在后台/前景序列之后显示该问题。

考虑保存在myprogram.py中的以下python程序:

import curses, subprocess

# Function that does nothing
def f(*args, **kwargs):
    pass

curses.wrapper(f)

# Call vi to open a file 
subprocess.call("vi /tmp/foo", shell=True)

重新解决问题的步骤:

  1. 运行程序:python myprogram.py
  2. 开始vi编辑文件/tmp/foo
  3. 当我点击ctrl-z时,它会让我回到我的shell
  4. 当我使用fg
  5. 恢复该计划时
  6. 重新启动编辑器,但屏幕错误(全黑,编辑器未绘制)
  7. 删除curses.wrapper(f)行会使程序正常工作:程序恢复后,编辑器会正确绘制。

    我尝试了多项内容,比如将curses.wrapper(f)的调用替换为它实际执行的操作,最简单的示例(即调用initscrendwin)也导致同样的问题

    我正在跑步:

    • zsh 5.0.5,我也尝试过最新的鱼壳版
    • python 2.7.6
    • VIM - Vi IMproved 7.3

    我错过了什么?

2 个答案:

答案 0 :(得分:1)

这恰好是<div class="show-for-medium-up"> <li><input id="email" type="text" placeholder="email address" /></li> <li><input id="password" type="text" placeholder="password" /></li> </div> 中的一个错误或其下面的任何错误,它会忘记将信号处理程序恢复到之前的值。 这解决了它:

curses.wrapper

答案 1 :(得分:1)

curses.wrapper的源代码对信号没有什么特别之处。

在初始化期间(例如对initscr的调用),ncurses库会为这些信号添加处理程序:SIGINTSIGTERMSIGTSTPSIGWINCH 。无论出于何种原因(可能因为它是调用者不能直接看到的内部细节),这主要记录在NEWS文件中。

需要添加自己的信号处理程序的应用程序应该在ncurses初始化之后执行此操作(因为ncurses仅执行此操作一次)。由于curses应用程序可以切换到屏幕模式,因此信号处理程序保持活动状态,直到程序退出。例如,Python脚本可以多次调用curses.wrapper(虽然它可能无法正常工作,除非使用ncurses - X / Open说“portable applications must not call initscr more than once”)。

按照@lc2817的建议保存和恢复信号处理程序状态会起作用 - 但 是一种解决方法,因为它不优雅。如果修改curses.wrapper以向其添加某些状态,要记住之前是否已调用它,以及保存/恢复信号处理程序,则不需要解决方法。为了使其真正可移植,首次使用时应调用initscr,后续使用时应调用refresh