Python:使用子进程模块无法在另一个命令行应用程序中读/写

时间:2009-07-22 12:55:08

标签: python subprocess readline

我在Windows中使用Python 3.0并尝试自动化命令行应用程序的测试。用户可以在“测试中的应用程序”中键入命令,并将输出作为2个XML数据包返回。一个是数据包,另一个是数据包。通过分析这些数据包,我可以验证他的结果。我的代码如下

p = subprocess.Popen(SomeCmdAppl, stdout=subprocess.PIPE,

                   shell = True, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)

p.stdin.write((command + '\r\n').encode())
time.sleep(2.5)
testresult = p.stdout.readline()
testresult = testresult.decode()
print(testresult)

我无法恢复任何输出。它陷入了我尝试使用readline()读取输出的位置。我试过read()并且它也被卡住了

当我手动运行命令行应用程序并输入命令时,我将输出正确地作为两个xml数据包返回

Sent: <PivotNetMessage>
<MessageId>16f8addf-d366-4031-b3d3-5593efb9f7dd</MessageId>
<ConversationId>373323be-31dd-4858-a7f9-37d97e36eb36</ConversationId>
<SageId>4e1e7c04-4cea-49b2-8af1-64d0f348e621</SagaId>
<SourcePath>C:\Python30\PyNTEST</SourcePath>
<Command>echo</Command>
<Content>Hello</Content>
<Time>7/4/2009 11:16:41 PM</Time>
<ErrorCode>0</ErrorCode>
<ErrorInfo></ErrorInfo>
</PivotNetMessagSent>

Recv: <PivotNetMessage>
<MessageId>16f8addf-d366-4031-b3d3-5593efb9f7dd</MessageId>
<ConversationId>373323be-31dd-4858-a7f9-37d97e36eb36</ConversationId>
<SageId>4e1e7c04-4cea-49b2-8af1-64d0f348e621</SagaId>
<SourcePath>C:\PivotNet\Endpoints\Pipeline\Pipeline_2.0.0.202</SourcePath>
<Command>echo</Command>
<Content>Hello</Content>
<Time>7/4/2009 11:16:41 PM</Time>
<ErrorCode>0</ErrorCode>
<ErrorInfo></ErrorInfo>
</PivotNetMessage>

但是当我使用下面的communic()时,我得到了Sent数据包,从来没有得到Recv:数据包。为什么我错过了recv包?沟通(0应该从stdout。rt带来所有东西?

p = subprocess.Popen(SomeCmdAppl, stdout=subprocess.PIPE,

                   shell = True, stdin=subprocess.PIPE, stderr=subprocess.STDOUT)
p.stdin.write((command + '\r\n').encode())
time.sleep(2.5)
result = p.communicate()[0]
print(result)

有人可以帮我提供一个应该有效的示例代码吗?我不知道是否需要在单独的线程中进行读写。请帮我。我需要重复读/写。我可以使用python中的任何高级模块吗?我认为Pexpect模块在Windows中不起作用

3 个答案:

答案 0 :(得分:1)

这是一个受欢迎的问题,例如见:

(实际上,你应该在创建问题时看到这些......?!)。

我有两件感兴趣的事情:

  • p.stdin.write((command +'\ r \ n')。encode())也是缓冲,因此您的子进程可能甚至看不到它的输入。您可以尝试冲洗此管道。
  • 在其他一个问题中,建议对孩子进行stdout。 read()而不是 readline(),并且需要读取适当数量的字符。你可能想试试这个。

发布结果。

答案 1 :(得分:0)

尝试使用communicate而不是write发送您的输入:

result = p.communicate((command + '\r\n').encode())[0]

答案 2 :(得分:0)

您是否考虑过使用pexpect而不是子进程?它处理可能阻止您的代码工作的细节(如刷新缓冲区等)。它可能还没有用于Py3k,但它在2.x中运行良好。

请参阅:http://pexpect.sourceforge.net/pexpect.html