Python TTY 控制

7 投票
2 回答
4942 浏览
提问于 2025-04-16 17:05

我想我不太明白getty、agetty和mgetty这些程序在Linux或Unix机器上到底是干什么的。我可以用类似下面的方式在tty上启动一个shell:

TTY = '/dev/tty3'

cpid = os.fork()
if cpid == 0:
    os.closerange(0, 4)
    sys.stdin = open(TTY, 'r')
    sys.stdout = open(TTY, 'w')
    sys.stderr = open(TTY, 'w')
    os.execv(('/bin/bash',), ('bash',))

……如果我切换到tty3,那里会有一个正在运行的shell,但有些按键输入会被忽略,或者根本没有发送到shell。shell知道TTY的设置不正确,因为bash会提示类似“无法打开tty,作业控制已禁用”的信息。

我知道'termios'模块有一些函数可以改变TTY的设置,而'tty'模块就是用这个的,但我找不到一个用Python正确设置TTY并启动shell的例子。我觉得这应该是件简单的事,但我不知道该去哪里找。

看了*etty程序的源代码对我没有帮助——C语言对我来说就像希腊文一样 :-/

也许我只是没有找到正确的术语?有没有人过去用Python替代过*etty程序,并愿意分享一下他们的解释?

谢谢你们耐心回答我的基础问题 :)

2 个回答

0

你可以看看 *tty* 程序的源代码,了解它们是干什么的。

我猜这些程序主要是发出一些叫做 ioctl 的命令,用来把终端设置成程序通常需要的模式(比如登录的时候)。不过,有些程序可能还会询问用户名(而不是密码;登录是处理密码的)。

5

我看到你可能漏掉了至少两件事,可能还有更多:

首先,在子进程中,你需要在关闭旧的标准输入和标准输出之后,打开新的终端之前,调用 setsid()。这一步很重要,主要有两个作用:第一,它让你的新进程成为一个新会话的领导者;第二,它把新进程和之前的控制终端分开(仅仅关闭那个终端是不够的)。这样,当你打开新的终端时,它就会成为控制终端,这正是你想要的效果。

其次,你需要把 TERM 环境变量设置为新的终端类型。

撰写回答