简体   繁体   English

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

[英]Sending curses application's output to tty1

Goal目标

I'd like to make my curses Python application display its output on a Linux machine's first physical console (TTY1) by adding it to /etc/inittab , reloading init with telinit q and so on.我想让我的 curses Python 应用程序在 Linux 机器的第一个物理控制台 (TTY1) 上显示其输出,方法是将其添加到/etc/inittab ,使用telinit q重新加载 init 等等。

I'd like to avoid a hacky way of using IO redirection when starting it from /etc/inittab with:当从/etc/inittab启动它时,我想避免使用 IO 重定向的hacky 方式:

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

What I'm after is doing it natively from within my app, similar to the way getty does it, ie you use a command line argument to tell it on which TTY to listen to:我所追求的是在我的应用程序中以本机方式执行此操作,类似于getty执行此操作的方式,即您使用命令行参数来告诉它在哪个 TTY 上收听:

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

Example code示例代码

For simplicity, let's say I've written this very complex app that when invoked, prints some content using ncurses routines.为简单起见,假设我编写了这个非常复杂的应用程序,在调用时使用 ncurses 例程打印一些内容。

import curses

class CursesApp(object):

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

curses.wrapper(CursesApp)

The code I already have does everything I need, except that it only shows its output on the terminal it's run from.我已经拥有的代码做了我需要的一切,除了它只在运行它的终端上显示它的输出。 When invoked from inittab without the hacky redirection I mentioned above, it works but there's no output on TTY1.在没有我上面提到的 hacky 重定向的情况下从 inittab 调用时,它可以工作,但在 TTY1 上没有输出。

I know that init doesn't redirect input and output by itself, so that's expected.我知道 init 不会自己重定向输入和输出,所以这是意料之中的。

How would I need to modify my existing code to send its output to the requested TTY instead of STDOUT?我需要如何修改现有代码以将其输出发送到请求的 TTY 而不是 STDOUT?

PS.附注。 I'm not asking how to add support for command line arguments, I already have this but removed it from the code sample for brevity.我不是在问如何添加对命令行参数的支持,我已经有了这个,但为了简洁起见从代码示例中删除了它。

This is rather simple.这比较简单。 Just open the terminal device once for input and once for output;只需打开终端设备一次输入,一次输出; then duplicate the input descriptor to the active process' file descriptor 0, and output descriptor over file descriptors 1 and 2. Then close the other handles to the TTY:然后将输入描述符复制到活动进程的文件描述符 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)

I tested this with the cmd module running on TTY6:我用在 TTY6 上运行的cmd模块对此进行了测试:

import cmd
cmd.Cmd().cmdloop()

Works perfectly.完美运行。 With curses it is apparent from their looks that something is missing: TERM environment variable:使用诅咒,从它们的外观中可以明显看出缺少某些东西: TERM环境变量:

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

Execute all these statements before even importing curses and it should work.在导入curses之前执行所有这些语句,它应该可以工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM