诅咒。包装()在背景/前景序列之后弄乱终端

2024-04-16 17:22:19 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在调查一个错误,其中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. 它重新启动编辑器,但屏幕错误(全黑,编辑器未绘制)

删除curses.wrapper(f)行可以使程序正常工作:当程序恢复时,编辑器将正确绘制。

我尝试了多种方法,比如用实际操作替换对curses.wrapper(f)的调用,并且,最简单的例子(即调用initscrendwin)也会导致相同的问题。在

我在跑步:

  • zsh5.0.5,我也尝试过最新的鱼壳版本
  • python 2.7.6
  • VIM-Vi改进了7.3

我错过了什么?在


Tags: py程序终端foo错误绘制shell编辑器
2条回答

curses.wrapper的源代码对信号没有任何特殊之处。在

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

需要添加自己的信号处理程序的应用程序应该在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中的一个错误,或者是下面的任何东西,它忘记了将信号处理程序恢复到以前的值。 这样可以修复它:

import curses, subprocess
import signal

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

a = signal.getsignal(signal.SIGTSTP)

curses.wrapper(f)

signal.signal(signal.SIGTSTP, a)

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

相关问题 更多 >