将curses应用程序的输出发送到tty1

时间:2016-03-19 13:56:28

标签: python curses tty inittab

目标

我想让我的curses Python应用程序在Linux机器的第一个物理控制台(TTY1)上显示其输出,方法是将其添加到/etc/inittab,使用telinit q重新加载init,依此类推。

我希望避免使用IO重定向从/etc/inittab启动时使用IO重定向:

1:2345:respawn:/path/to/app.py > /dev/tty1 < /dev/tty1

我所追求的是从我的应用程序中本地执行,类似于getty的方式,即您使用命令行参数告诉它要听哪个TTY:

S0:2345:respawn:/sbin/getty -L ttyS1 115200 vt100

示例代码

为简单起见,假设我写了这个非常复杂的应用程序,在调用时,使用ncurses例程打印一些内容。

import curses

class CursesApp(object):

  def __init__(self, stdscr):
    self.stdscr = stdscr
    # Code producing some output, accepting user input, etc.
    # ...    

curses.wrapper(CursesApp)

我已经拥有的代码可以完成我需要的一切,除了它只在它运行的终端上显示其输出。当我从inittab调用而没有上面提到的hacky重定向时,它可以工作,但TTY1上没有输出。

我知道init不会自行重定向输入和输出,所以这是预期的。

我如何修改现有代码以将其输出发送到请求的TTY而不是STDOUT?

PS。我不是问如何添加对命令行参数的支持,我已经有了这个但是为了简洁而从代码示例中删除了它。

1 个答案:

答案 0 :(得分:2)

这很简单。只需打开终端设备一次输入,一次打开输出;然后将输入描述符复制到活动进程&#39;文件描述符0和文件描述符1和2上的输出描述符。然后关闭TTY的其他句柄:

import os
import sys

with open('/dev/tty6', 'rb') as inf, open('/dev/tty6', 'wb') as outf:
    os.dup2(inf.fileno(), 0)
    os.dup2(outf.fileno(), 1)
    os.dup2(outf.fileno(), 2)

我使用在TTY6上运行的cmd module进行了测试:

import cmd
cmd.Cmd().cmdloop()

完美无缺。使用curses,从外观上可以看出缺少某些东西:TERM环境变量:

os.environ['TERM'] = 'linux'

在导入curses之前执行所有这些语句,它应该有效。