【问题标题】:Using set input for stdin based on output from stdout with python subprocess根据带有 python 子进程的 stdout 的输出为 stdin 设置输入
【发布时间】:2013-05-16 04:31:50
【问题描述】:

我想使用 subprocess.Popen 从 python 自动安装一个软件。在安装过程中,该软件会输出一些信息,然后询问用户几个问题(例如,是否同意软件许可或安装软件)。对于这些问题,我想从 pythong 代码中自动回答。但是,我尝试了几种方法,但没有一个对我有用。知道如何制作吗?预期的伪代码如下(肯定是这段代码不行)。

p = subprocess.Popen(['myprogram'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.STDOUT))

while (p.poll() == None):
  line = p.stdout.readline()
  if not line: 
    break
  else:
    print line.strip()
    if line == 'Do you accept license agreement (YES/NO)':
      p.stdin.write('YES/n')
    elif line == 'Do you want to install this software (YES/NO)':
      p.stdin.write('YES/n')

【问题讨论】:

  • 如果你的意思是'YES\n',不要写'YES/n'。此外,line 的末尾可能包含\nprint line.strip() 不会那样做。相反,请在适当的时候使用line = line.strip()
  • 此外,for line in p.stdout:for line in iter(p.stdout.readline, ''): 可能会更好。
  • 你是对的,应该是'YES\n'。然而,这一点并不重要。问题是当有一个需要用户输入的问题时,程序会暂停(甚至不显示/检索该问题)。当我强行停止它时,我发现它正在 p.stdout.readline() 处等待。因此,不知道该怎么办。
  • 我按照 Thomas Fenz 的建议尝试了 pexpect。但它没有用。特别是我做了如下代码 p = pexpect.spawn('my program') p.expect('Do you accept license agreement (YES/NO)') p.sendline('YES')。但是我遇到了超时错误。我猜是因为许可协议的输出很长,因此解析会产生超时

标签: python subprocess popen


【解决方案1】:

感谢托马斯·芬兹。 pypi.python.org/pypi/pexpect 在这种情况下非常出色。在我之前的评论中,我说它不起作用,因为我在模式规范中犯了一个错误。特别是,我使用了 p.expect('Do you accept license agreement? (YES/NO)')。在这种情况下,问号是一个错误。由于它是元字符,因此无法匹配模式,因此发生了 TIMEOUT。

【讨论】:

    猜你喜欢
    • 2021-06-02
    • 2016-08-11
    • 1970-01-01
    • 2017-04-16
    • 2023-03-23
    • 2012-09-27
    • 2014-02-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多