我写一个命令行应用程序Python中的测试框架。 该应用程序将创建目录,在该标准输出的当前目录将输出调用其他的shell脚本。
我试图把{Python的子过程,命令}组合等同于{硒,浏览器}。 如果产量预计第一个组件起到在第二和检查的东西。 我面临着以下问题
- 器一起构建需要一个命令,并完成该命令后返回。 我要的是一个活生生的句柄的过程,所以我可以运行更多的命令+验证和最后关闭做一次壳
- 我还好有写一些基础的代码为achieveing这一点,因为我们有很多需要这样的测试命令行应用程序。
下面是我运行示例代码
p = subprocess.Popen("/bin/bash", cwd = test_dir)
p.communicate(input = "hostname") --> I expect the hostname to be printed out
p.communicate(input = "time") --> I expect current time to be printed out
但该过程将挂起或可能是我做错了什么。 还有我怎么“抢”该子过程的输出,所以我可以断言的东西存在?
subprocess.Popen
允许你启动进程后继续执行。 该Popen
对象公开wait()
poll()
和许多其他的方法在运行时,与子进程进行通信。 是不是你需要什么?
见POPEN构造和Popen
对象描述的详细信息。
下面是运行在Unix系统Bash和执行命令的一个小例子:
from subprocess import Popen, PIPE
p = Popen (['/bin/sh'], stdout=PIPE, stderr=PIPE, stdin=PIPE)
sout, serr = p.communicate('ls\n')
print 'OUT:'
print sout
print 'ERR:'
print serr
UPD: communicate()
等待进程终止。 如果你不需要,你可以直接使用适当的管道,但通常给你相当丑陋的代码。
UPD2:你更新的问题。 是的,你可以不叫communicate
的一个过程两次。 您既可以给你需要在一个单一的调用执行的所有命令communicate
和检查整个输出,或用管道(工作Popen.stdin
, Popen.stdout
, Popen.stderr
)。 如果可能的话,我强烈建议(使用第一个解决方案communicate
)。
否则,你将不得不把指令输入,等待一段时间所需的输出。 你需要的是非阻塞读,避免悬空时,有什么可看。 这里是一个配方如何模拟上使用线程管非阻塞模式。 该代码是丑陋,奇怪的复杂,这样一个微不足道的目的,但这是它是如何做。
另一种选择,可以使用p.stdout.fileno()
用于select.select()
调用,但不会在Windows上运行(在Windows上select
从始发的WinSock仅对象工作)。 你可能会认为,如果你不能在Windows。
除了使用普通的subprocess
,你可能会发现Python的SH库非常有用:
http://amoffat.github.com/sh/
下面是一个例子,如何建立符合SH异步交互循环:
http://amoffat.github.com/sh/tutorials/2-interacting_with_processes.html
另一个(旧)库解决这个问题是Pexpect的:
http://www.noah.org/wiki/pexpect