【问题标题】:Issuing commands to psuedo shells (pty)向伪 shell (pty) 发出命令
【发布时间】:2014-01-29 20:52:07
【问题描述】:

我尝试使用子进程、popen、os.spawn 来运行进程,但似乎需要一个伪终端。

import pty

(master, slave) = pty.openpty()

os.write(master, "ls -l")

应该将“ls -l”发送到从 tty... 我试图读取响应 os.read(master, 1024),但没有可用的内容。

编辑:

还尝试创建 pty,然后在子进程中打开调用 - 仍然没有工作。

import pty
import subprocess

(master, slave) = os.openpty()
p = subprocess.Popen("ls", close_fds=True, shell=slave, stdin=slave, stdout=slave)

类似的:

Send command and exit using python pty pseudo terminal process

How do *nix pseudo-terminals work ? What's the master/slave channel?

【问题讨论】:

  • 您不需要 pty 来运行 ls。管道可以很好地工作。你在那里尝试了什么?
  • 我正在使用ls 来测试功能。
  • 在您的编辑中,您正在混合 pty 和 pipe。不要那样做。使用其中一种。
  • 那么我如何在pty 中获得ls 的输出?
  • 我建议从返回的文件描述符中使用 forkpty 和 os.read()。这是一个示例proctools.py

标签: python shell pty


【解决方案1】:

使用pty.spawn 代替os.spawn。这是一个在单独的 pty 中运行命令并将其输出作为字符串返回的函数:

import os
import pty

def inpty(argv):
  output = []
  def reader(fd):
    c = os.read(fd, 1024)
    while c:
      output.append(c)
      c = os.read(fd, 1024)

  pty.spawn(argv, master_read=reader)
  return ''.join(output)

print "Command output: " + inpty(["ls", "-l"])

【讨论】:

  • 在 Python 3 中,将 return 替换为:return b''.join(output).decode('utf-8')