我正在使用ncurses绘制TUI。问题是,每当我的程序出现段错误时,我的终端就会乱掉。我看不到我正在输入的内容。这很痛苦,因为我正在通过ssh工作。我通过使用screen来减轻一些影响。
我想知道是否有一个命令可以在ncurses发生段错误后刷新我的终端,使其恢复正常。
命令,
stty sane
完成了工作。如果回车键无效,您可以使用 ^J
。
stty sane ^J
有时候 CR/LF 的解释可能会出问题,所以要明确使用 ^J
。ncurses(任何curses实现)在运行时将终端模式设置为raw和noecho,并允许应用程序使用raw和noraw、echo和noecho函数来模拟这些模式。这样做是为了提高性能,避免在这些模式之间切换时等待。
当应用程序调用endwin
时,ncurses会恢复终端模式。它还可以为reset_shell_mode执行此操作,但endwin
更常用。
如果您的应用程序崩溃或退出而没有使用endwin
恢复终端模式,则最明显的问题是您无法看到自己输入的内容,并且按下enter键无效。
ncurses提供了一个信号处理程序来捕获用户发起的信号SIGINT
、SIGTERM
,并在捕获这些信号时进行清理。它不会尝试捕获SIGSEGV
,因为此时您的应用程序已经停止运行,试图复活它以修复问题是没有意义的。
有些人可能会建议使用stty sane
来恢复终端模式。这“可以”工作,但在Unix平台上可能会使您的erase键设置为意外值。对于Linux和现代BSD系统,它按预期工作。
然而,在此之外,ncurses通常会重置
如果您的应用程序使用了这些功能,则reset
命令是合适的选择。它通常也会清除屏幕(可能不是想要的)。而且它使用的字符较少:
reset
controlJ
stty sane
controlJ
进一步阅读:
reset
在Ubuntu上也对我有用,但可能有点过度。 最好的方法是设置一个别名,例如:
alias 'clean'='stty sane;clear;'
我在我的 .bash_aliases 文件中添加了这个命令,因为我发现在调试中经常需要使用它。
tput cnorm
**更明确,更有可能奏效。 - Thomas Dickey为 SIGSEGV
等写一个信号处理程序,该程序调用 endwin()
。
我最近在Mac OSX终端遇到了这个问题。以下一组命令有效,而stty sane则无效。
stty discard '^O'
stty dsusp '^Y'
stty eof '^D'
stty eol '^@'
stty eol2 '^@'
stty erase '^?'
stty intr '^C'
stty kill '^U'
stty lnext '^V'
stty min 1
stty quit '^\'
stty reprint '^R'
stty start '^Q'
stty status '^T'
stty stop '^S'
stty susp '^Z'
stty time 0
stty werase '^W'