2013-03-20 17 views
3

我试图在这里遵循这样的回答:https://stackoverflow.com/a/5087695/343381发送多条命令是bash shell必须共享环境

我有一个单一的环境中需要执行多个命令的bash。我的测试案例很简单:

import subprocess 
cmd = subprocess.Popen(['bash'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

# Write the first command 
command = "export greeting=hello\n" 
cmd.stdin.write(command) 
cmd.stdin.flush() # Must include this to ensure data is passed to child process 
result = cmd.stdout.read() 
print result 

# Write the second command 
command = "echo $greeting world\n" 
cmd.stdin.write(command) 
cmd.stdin.flush() # Must include this to ensure data is passed to child process 
result = cmd.stdout.read() 
print result 

我预计(基于参考答案)发生的是,我看到“Hello World”字样。实际上发生的是它挂在第一个cmd.stdout.read()上,并且永远不会返回。

任何人都可以解释为什么cmd.stdout.read()永远不会返回?

注:

  • 这是绝对必要的,我从运行巨蟒在同一环境中的多个的bash命令。因此,subprocess.communicate()没有帮助,因为它等待进程终止。
  • 请注意,在我的真实测试案例中,它不是要执行的bash命令的静态列表。逻辑更加动态。我没有选择一次运行所有这些选项。
+1

啊,现在看看;我怀疑你需要轮询管道以查看是否有任何内容。你也可以尝试只读第二个命令'stdin' pipe而不读取'stdout'。 – 2013-03-20 21:35:00

回答

2

您这里有两个问题:

  1. 你的第一个命令不产生任何输出。所以第一次读取块等待一些。
  2. 您正在使用read()而不是readline() - read()会阻塞,直到有足够的数据可用。

以下修改后的代码(与Martjin的投票建议更新)正常工作:

import subprocess 
import select 

cmd = subprocess.Popen(['bash'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 

poll = select.poll() 
poll.register(cmd.stdout.fileno(),select.POLLIN) 

# Write the first command 
command = "export greeting=hello\n" 
cmd.stdin.write(command) 
cmd.stdin.flush() # Must include this to ensure data is passed to child process 
ready = poll.poll(500) 
if ready: 
    result = cmd.stdout.readline() 
    print result 

# Write the second command 
command = "echo $greeting world\n" 
cmd.stdin.write(command) 
cmd.stdin.flush() # Must include this to ensure data is passed to child process 
ready = poll.poll(500) 
if ready: 
    result = cmd.stdout.readline() 
    print result 

上面有一个500毫秒的超时 - 调整您的需求。

+0

@MartjinPieters - 道歉(刚刚注意到你的评论)。准备删除,但read()vs readline()很重要。 – isedev 2013-03-20 21:58:10

+0

感谢您提供投票代码。对于从未使用过该功能的人来说,如何为新数据轮询stdout并不明显。 – 2013-03-20 22:46:19

+0

在Python 2.7.10上,我不适用于我的AttributeError:'模块'对象没有属性'poll' – 2016-03-15 09:35:43