【发布时间】:2017-05-23 09:58:24
【问题描述】:
我需要在 Python 中的一个单独进程中运行一个交互式 Bash 实例,并使用它自己的专用 TTY(我不能使用 pexpect)。 我使用了我在类似程序中经常看到的这段代码sn-p:
master, slave = pty.openpty()
p = subprocess.Popen(["/bin/bash", "-i"], stdin=slave, stdout=slave, stderr=slave)
os.close(slave)
x = os.read(master, 1026)
print x
subprocess.Popen.kill(p)
os.close(master)
但是当我运行它时,我得到以下输出:
$ ./pty_try.py
bash: cannot set terminal process group (10790): Inappropriate ioctl for device
bash: no job control in this shell
运行的 Strace 显示一些错误:
...
readlink("/usr/bin/python2.7", 0x7ffc8db02510, 4096) = -1 EINVAL (Invalid argument)
...
ioctl(3, SNDCTL_TMR_TIMEBASE or SNDRV_TIMER_IOCTL_NEXT_DEVICE or TCGETS, 0x7ffc8db03590) = -1 ENOTTY (Inappropriate ioctl for device)
...
readlink("./pty_try.py", 0x7ffc8db00610, 4096) = -1 EINVAL (Invalid argument)
代码 sn-p 看起来很简单,Bash 没有得到它需要的东西吗?这可能是什么问题?
【问题讨论】:
-
这很正常——你有一个没有作业控制的交互式shell。
-
如果你也想要作业控制,你需要你的 shell 成为进程的领导者——也就是开始新的“会话”,它是通过
start_new_session=True关键字参数到Popen来实现的(从 Python 3.2 开始) .如果您需要更多控制,请使用preexec_fn=... -
好吧,这听起来很合理。我了解
start_new_session=True仅与>3.2 相关。 2.7中是否有等价物?对不起,可能应该在问题中提到python版本。 -
您可以通过
preexec_fn中的setsid()通过ctypes手动调用
标签: python linux bash python-2.x tty