【问题标题】:Writing input to a process opened with Popen将输入写入使用 Popen 打开的进程
【发布时间】:2022-01-26 07:07:35
【问题描述】:

我有一个名为 my_program 的程序来操作系统。该程序在 Linux 上运行,我正在尝试使用 Python 将其自动化。 my_program 不断生成输出,并假设接收输入并对其做出响应。 当我在 bash 中运行 my_program 时,它确实可以正常工作,我从程序接收到恒定输出,当我按下某个序列(例如 /3 更改系统模式)时,程序以输出响应.

开始我正在使用的过程:

self.process = Popen(my_program,stdin=PIPE,stdout=PIPE,text=True)

为了将输入写入我正在使用的系统:

self.process.stdin.write('/3')

但是写的好像不行,我也试过用:

self.process.communicate('/3)

但由于我的系统不断生成输出,它使进程死机并且整个程序卡住了。

对于写入不断生成输出的进程的任何解决方案?

编辑: 我认为我无法提供可以重现该问题的代码,因为我使用的是我公司拥有的独特软件,但它是这样的:

self.process = Popen(my_program,stdin=PIPE,stdout=PIPE,text=True)
self.process.stdin.write('/3')
# try to find a specific string that indicated that the input string was received
string_received = False
while(string_received = False):
    response = self.process.stdout.readline().strip()
    if (response == expected_string): 
       break

【问题讨论】:

  • @pynexj 我编辑了我的问题以包含更清晰的内容,tnx
  • “似乎不起作用”——这是一种解释,但缺少可观察到的事实。请创建一个minimal reproducible example 并展示您所看到的内容。
  • 在刷新缓冲区之前,只写几个字节不会做任何事情。您可以在创建子进程时设置最小缓冲区或关闭缓冲。
  • @tripleee 你能详细说明一下吗?

标签: python bash


【解决方案1】:

除非您另有特别要求,否则操作系统会在进程之间实现缓冲 I/O。

简而言之,当输出缓冲区填满时,或者(使用默认选项)写入换行符时,输出缓冲区将被刷新和写入。

您可以在创建Popen 对象时禁用缓冲:

self.process = Popen(my_program, stdin=PIPE, stdout=PIPE, text=True, bufsize=1)

...或者当你想强制写入时,你可以显式地flush()文件句柄。

self.process.stdin.flush()

但是,正如文档警告您的那样,如果您无法预测子进程何时可以读取以及何时可以写入,您很容易陷入死锁。更易于维护的解决方案可能是通过pexpect 或类似方式运行子进程。

【讨论】:

  • 一些更正:flush() 处理刷新用户模式(不是“操作系统实现”)缓冲区。并且bufsize=1 正在打开行缓冲,而不是 1 字节缓冲区,也没有完全禁用缓冲;由于 OP 没有写换行符,它不会解决像 '/3' 这样的短写的问题。即使使用flush,他们可能仍然会在my_program 方面遇到问题(忽略“双向通信导致死锁问题”),因为它可能在stdin 上有缓冲区,可能会干扰接收立即数据。简而言之,您的最后一段是这里最好的建议。
  • 我也试过 pexpect 但 my_program 没有响应 sendline('/3)。 my_program 是用 C 编写的,它基本上将输出写入屏幕,同时等待 getchar() 获取的来自键盘的用户输入。我尝试打印 my_program 作为输入接收的内容,而我尝试的所有书写方法的输入(除非我在 bash 中使用键盘输入运行它时)my_program 根本无法识别。
  • 如果程序是你自己的,可能让它监听网络套接字。
  • @Kuper sendline() 将发送一个额外的 ENTER 字符。使用send(),因为您只想发送/3
猜你喜欢
  • 2019-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-22
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 2011-12-20
相关资源
最近更新 更多