Python TTY 控制
我想我不清楚 getty/agetty/mgtty 程序在 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 程序,并且有愿意分享的解释吗?
感谢您解答我的基本问题:)
I guess I'm not clear on what what the function of the getty/agetty/mgetty programs are on a linux/unix machine. I can start a shell on a tty with something like this:
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',))
..and if i switch over to tty3, there is a shell running- but some keystrokes are ignored / are never being sent to the shell. the shell knows the TTY settings are not correct because bash will say something like 'unable to open tty, job control disabled'
I know the 'termios' module has functions to change the settings on the TTY, which is what the 'tty' module uses, but i am unable to find an example of python setting the TTY correctly and starting a shell. I feel like it should be something simple, but i don't know where to look.
looking at the source for the *etty programs didn't help me- C looks like greek to me :-/
Maybe im just not looking for the right terms? Anyone replaced the *etty programs with Python in the past and have an explanation they would care to share?
Thanks for entertaining my basic question :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我可以看到您至少缺少两件事 - 可能还有更多:
首先,您需要在关闭旧的标准输入/标准输出之后、打开之前在子进程中调用
setsid()
新的 TTY。这做了两件重要的事情 - 它使您的新进程成为新会话的领导者,并将其与之前的控制终端解除关联(仅关闭该终端不够)。这意味着当您打开新的 tty 时,它将成为控制终端,这正是您想要的。其次,您需要设置
TERM
环境变量以匹配新的tty。I can see at least two things you're missing - there may be more:
Firstly, you need to call
setsid()
in the child process after closing the old standard input/standard output, and before opening the new TTY. This does two important things - it makes your new process the leader of a new session, and it disassociates it from its previous controlling terminal (merely closing that terminal is not sufficient). This will mean that when you open the new tty, it will become the controlling terminal, which is what you want.Secondly, you need to set the
TERM
environment variable to match the new tty.您应该查看 *tty* 程序的源代码,看看它们的作用。
我的猜测是,他们主要发出一堆 ioctl 命令来将终端初始化为程序通常期望的模式(例如用于登录等)。然而,其中一些也可能会提示输入用户名(不是密码;登录就是这样)。
You should have a look at the source of the *tty* programs, to see what they do.
My guess is that they mostly issue a bunch of ioctl commands to initialise the terminal into the mode that programs normally expect (e.g. for login etc). However some of them may also prompt for a username (not password; login does that).