当处于curses模式下,标准输出(stdout)和标准错误(stderr)去哪里了?

7
当curses处于活动状态时,标准输出和标准错误输出去哪里了?
import curses, sys

def test_streams():
    print "stdout"
    print >>sys.stderr, "stderr"

def curses_mode(stdscr):
    test_streams()

test_streams()
curses.wrapper(curses_mode)

实际输出结果为

stdout
stderr

更新0

期望输出为

stdout
stderr
stdout
stderr

在终端中进入和退出 curses 模式,但最终显示的文本不发生变化。

1个回答

7

激活curses会保存终端文本屏幕的当前内容并清除该屏幕;退出curses会恢复屏幕的内容(在curses自身统治期间放置在屏幕上的任何内容都将被丢弃)。尝试使用您代码的这个变体,您将更好地了解发生了什么:

import curses, sys, time

def test_streams(wot):
    print wot, "stdout"
    print >>sys.stderr, wot, "stderr"

def curses_mode(stdscr):
    test_streams("wrap")
    time.sleep(1.0)

test_streams("before")
curses.wrapper(curses_mode)
test_streams("after")

你会注意到屏幕上的wrap stderr在睡眠期间出现了一秒钟 - 它覆盖了stdout部分 - 然后它消失了,你会看到四行之前和之后的内容在现在平静的屏幕上(如果你关心,你可以添加其他的睡眠来跟踪更多细节)。


你能说一下这些流的输出去了哪里吗?据我所知,stderr被“忽略”了,而stdout与终端指令交错,我猜想如果你将它们中的任何一个转储出来,那么数据会根据终端的不同而有所不同。 - Matt Joiner
@Matt,无论是在Mac还是Linux上,使用以上给出的代码,在一个空字符串中我看到了“wrap stderr”字样,所以我不知道你为什么说stderr被“忽略”了。它们两个应该会像以前一样进入它们原本的位置,即/dev/tty(您可能需要刷新它们,因为它们的缓冲状态可能已经被暂时改变,这取决于您的操作系统和库)。 - Alex Martelli
2
NB:curses库不保存当前屏幕内容;如果存在这样的“野兽”,它默认切换到备用屏幕(终端术语🙂*),并在退出时切换回普通屏幕。如果终端(实际上是terminfo数据)没有备用屏幕,curses只会清除屏幕。比较一个在例如/usr/bin/xterm(或某些最新终端)下运行的curses程序和在/usr/bin/screen下运行的curses程序(虚拟终端“screen”没有备用屏幕)。我刚写了一个非常混乱的注释,但我无法做其他事情:) - tzot
2
终端信息(terminfo)条目可以用于切换屏幕,这些条目包括:smcup(通常为 ^[[?1049h)和 rmcup(通常为 ^[[?1049l)。您可以通过向 shell 发出 tput smcuptput rmcup 命令来手动切换屏幕。 - tzot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接