gpt4 book ai didi

python - 像命令行模拟器一样使用 python 子进程模块

转载 作者:太空宇宙 更新时间:2023-11-04 01:29:13 24 4
gpt4 key购买 nike

我正在用 Python 为命令行应用程序编写测试框架。应用程序将创建目录,调用当前目录中的其他 shell 脚本,并在 Stdout 上输出。

我试图将 {Python-SubProcess, CommandLine} 组合视为等同于 {Selenium, Browser}。第一个组件在第二个组件上播放某些内容,并检查是否有预期的输出。我面临以下问题

  1. Popen 构造接受一个命令并在该命令完成后返回。我想要的是进程的实时句柄,这样我就可以运行进一步的命令 + 验证,并在完成后最终关闭 shell
  2. 我可以编写一些基础架构代码来实现这一目标,因为我们有很多命令行应用程序需要这样的测试。

这是我正在运行的示例代码

 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 constructorPopen 对象描述以获取详细信息。

这是一个在 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.stdinPopen.标准输出Popen.stderr)。如果可能,我强烈推荐第一种解决方案(使用communicate)。

否则你将不得不输入命令并等待一段时间以获得所需的输出。您需要的是非阻塞读取,以避免在没有可读内容时挂起。 Here是如何使用线程在管道上模拟非阻塞模式的秘诀。对于这样一个微不足道的目的,代码很丑陋而且异常复杂,但这就是它的完成方式。

另一个选项可能是使用 p.stdout.fileno() 进行 select.select() 调用,但这在 Windows 上不起作用(在 Windows select 仅对源自 WinSock 的对象进行操作)。如果你不是在 Windows 上,你可以考虑它。

关于python - 像命令行模拟器一样使用 python 子进程模块,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15205597/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com