【问题标题】:Using Python to run executable and fill in user input使用 Python 运行可执行文件并填写用户输入
【发布时间】:2014-02-26 15:19:30
【问题描述】:

我正在尝试使用 Python 来自动化涉及调用 Fortran 可执行文件和提交一些用户输入的过程。我花了几个小时阅读类似的问题并尝试不同的事情,但没有任何运气。这是一个显示我上次尝试的最小示例

#!/usr/bin/python

import subprocess

# Calling executable 
ps = subprocess.Popen('fortranExecutable',shell=True,stdin=subprocess.PIPE)
ps.communicate('argument 1')
ps.communicate('argument 2')

但是,当我尝试运行它时,我收到以下错误:

  File "gridGen.py", line 216, in <module>
    ps.communicate(outputName)
  File "/opt/apps/python/epd/7.2.2/lib/python2.7/subprocess.py", line 737, in communicate
    self.stdin.write(input)
ValueError: I/O operation on closed file

非常感谢任何建议或指示。

编辑:

当我调用 Fortran 可执行文件时,它要求用户输入如下:

fortranExecutable
Enter name of input file: 'this is where I want to put argument 1'
Enter name of output file: 'this is where I want to put argument 2'

不知何故,我需要运行可执行文件,等待它要求用户输入,然后提供该输入。

【问题讨论】:

    标签: python subprocess stdin communicate


    【解决方案1】:

    如果输入不依赖于之前的答案,那么您可以使用 .communicate() 一次性传递所有答案:

    import os
    from subprocess import Popen, PIPE
    
    p = Popen('fortranExecutable', stdin=PIPE) #NOTE: no shell=True here
    p.communicate(os.linesep.join(["input 1", "input 2"]))
    

    .communicate() 等待进程终止,因此您最多可以调用一次。

    【讨论】:

    • 它对我来说是这样的TypeError: a bytes-like object is required, not 'str'
    • @KuneMohith 代码适用于 Python 2(其中 strbytes 类型)。在当前 Python 版本上将 text=Trueencoding 参数传递给 Popen()。
    • @KuneMohith:例如,subprocess.run('fortranExecutable', input="\n".join(["input 1", "input 2"]), text=True)(在 Python 3.7 上测试)
    【解决方案2】:

    由于spec says communicate() 等待子进程终止,因此第二次调用将针对已完成的进程。

    如果您想与进程交互,请改用p.stdin&Co(注意死锁警告)。

    【讨论】:

      【解决方案3】:

      当你到达 ps.communicate('argument 2') 时,ps 进程已经关闭,因为 ps.communicate('argument 1') 一直等到 EOF。 我认为,如果您想在 stdin 上多次写入,您可能必须使用:

      ps.stdin.write('argument 1')
      ps.stdin.write('argument 2')
      

      【讨论】:

      • 我试过了,但还是报错。请参阅上面的编辑以澄清问题。
      【解决方案4】:

      您的参数不应传递给通信。它们应该在对 Popen 的调用中给出,例如: http://docs.python.org/2/library/subprocess.html#subprocess.Popen

      >>> import shlex, subprocess
      >>> command_line = raw_input()
      /bin/vikings -input eggs.txt -output "spam spam.txt" -cmd "echo '$MONEY'"
      >>> args = shlex.split(command_line)
      >>> print args
      ['/bin/vikings', '-input', 'eggs.txt', '-output', 'spam spam.txt', '-cmd', "echo '$MONEY'"]
      >>> p = subprocess.Popen(args) # Success!
      

      【讨论】:

      • 问题是可执行文件运行,然后要求用户输入。我需要等到请求用户输入,然后填写该输入。共有三个输入。
      猜你喜欢
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-01
      • 1970-01-01
      • 1970-01-01
      • 2021-05-12
      • 1970-01-01
      相关资源
      最近更新 更多