python - 为什么 python.subprocess 在 proc.communicate() 之后挂起?

标签 python subprocess

我有一个名为 my_own_exe 的交互式程序。首先,它打印出 alive,然后你输入 S\n,然后它再次打印出 alive。最后输入 L\n。它进行一些处理并退出。

但是,当我从以下 python 脚本调用它时,程序似乎在打印出第一个“活着”后挂起。

这里有人能告诉我为什么会这样吗?

//看完后续(谢谢大家),修改代码如下:

import subprocess
import time

base_command = "./AO_FelixStrategy_UnitTest --bats 31441 --chix 12467 --enxutp 31884 --turq 26372 --symbol SOGN --target_date " + '2009-Oct-16'
print base_command

proc2 = subprocess.Popen(base_command, shell=True , stdin=subprocess.PIPE,)

time.sleep(2);
print "aliv"
proc2.communicate('S\n')

print "alive"
time.sleep(6)

print "alive"
print proc2.communicate('L\n')
time.sleep(6)

程序现在可以很好地处理第一个输入“S\n”,但随后停止,第二个“L\n”有点被忽略了。

谁能告诉我为什么会这样?

最佳答案

来自docs for communicate :

Interact with process: Send data to stdin. Read data from stdout and stderr, until end-of-file is reached. Wait for process to terminate.

所以在 communicate() 运行后,进程已经终止

如果你想在不等待进程停止的情况下写入和读取:

  • 永远不要使用shell=True - 它不必要地调用一个shell来调用你的程序,所以你和你之间会有另一个进程你的程序。这有很多不愉快的副作用。默认值是 shell=False 所以你应该坚持使用它。 将 Popen 行更改为:

    p = subprocess.Popen(["./AO_FelixStrategy_UnitTest",
                          "--bats", "31441", "--chix", "12467",
                          "--enxutp", "31884", "--turq", "26372",
                          "--symbol", "SOGN", "--target_date", '2009-Oct-16'],
                         stdin=subprocess.PIPE, 
                         stdout=subprocess.PIPE)
    
  • 使用p.stdin.write 写入进程。使用 p.stdout.read 从中读取。

  • 如果没有可读取的内容,则调用 p.stdout.read 将阻塞。如果写入缓冲区已满,调用 p.stdin.write 将阻塞。所以你必须确保你有一些东西可以读/写——你在 unix 操作系统上使用 select 来做到这一点。不幸的是,在 Windows 上你必须求助于线程。至少那是 Popen.communicate 在内部所做的事情。
  • 如果您没有编写 AO_FelixStrategy_UnitTest 那么您可能会遇到其他问题:
    • 它可能是从其他地方读取的,而不是标准输入。一些程序直接从终端读取,另一些程序使用一些 OS API 来读取。这意味着写入标准输入的数据不会进入程序。这通常适用于密码提示。
    • 请记住,您必须考虑 AO_FelixStrategy_UnitTest 缓冲区。默认情况下,标准 C PIPE 通信被缓冲,因此在关闭输入端之前您可能看不到任何输出(通过执行 p.stdin.close()。除非 AO_FelixStrategy_UnitTest 定期刷新输出。

根据您的描述,这是一些示例代码。它的工作取决于 AO_FelixStrategy_UnitTest 的开发方式:

p = subprocess.Popen(["./AO_FelixStrategy_UnitTest",
                      "--bats", "31441", "--chix", "12467",
                      "--enxutp", "31884", "--turq", "26372",
                      "--symbol", "SOGN", "--target_date", '2009-Oct-16'],
                     stdin=subprocess.PIPE, 
                     stdout=subprocess.PIPE)
output = p.communicate('S\nL\n')[0]
print output

关于python - 为什么 python.subprocess 在 proc.communicate() 之后挂起?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2408650/

相关文章:

linux - <() 在 Bash 中做什么?

python - 从标准输入管道输入时 ffmpeg 损坏

linux - subprocess.Popen : does not retun complete output , 当通过 crontab 运行时

python - 迭代生成器时调用 iter 和 next

python - 数半金字塔 Python

python - 在 python 中使用 kinesis 流

Python 子进程调用返回 "command not found",终端正确执行

python - 如何在 IPython 中完成 win32com 代码?

python - 如何将数据帧合并到第二个数据帧中的每一行?

python - 通过子进程从另一个 python 脚本调用 python 脚本时导入错误的包