我正在调查一个错误,其中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)
重新生成问题的步骤:
python myprogram.py
/tmp/foo
ctrl-z
时,它会让我回到我的shellfg
继续程序时删除curses.wrapper(f)
行可以使程序正常工作:当程序恢复时,编辑器将正确绘制。
我尝试了多种方法,比如用实际操作替换对curses.wrapper(f)
的调用,并且,最简单的例子(即调用initscr
,endwin
)也会导致相同的问题。在
我在跑步:
我错过了什么?在
curses.wrapper的源代码对信号没有任何特殊之处。在
在初始化期间(例如对^{} 的调用),ncurses库为这些信号添加处理程序:} 文件中。在
SIGINT
,SIGTERM
,SIGTSTP
,SIGWINCH
。无论出于什么原因(可能是因为它是一个内部细节,调用者无法直接看到),这主要记录在^{需要添加自己的信号处理程序的应用程序应该在ncurses初始化之后执行此操作(因为ncurses只执行一次)。因为curses应用程序可以切换到屏幕模式/从屏幕模式切换,信号处理程序将保持活动状态,直到程序退出。例如,Python脚本可以多次调用
curses.wrapper
(尽管它可能无法正常工作,除非ncurses X/Open声明“portable applications must not call initscr more than once”)。在按照@lc2817的建议保存和恢复信号处理程序状态是可行的,但这是一种解决办法,因为它不优雅。如果修改
curses.wrapper
以向其添加一些状态,以记住之前是否调用过它,并保存/恢复信号处理程序,则无需解决此问题。为了使其真正的可移植性,应该在第一次使用时调用initscr
,在随后的使用中调用refresh
。在这恰好是
curses.wrapper
中的一个错误,或者是下面的任何东西,它忘记了将信号处理程序恢复到以前的值。 这样可以修复它:相关问题 更多 >
编程相关推荐