2

我正在编写一个用于使用 oracle exp/imp 命令并通过 sqlplus 启动 sql-scripts 的 GUI。subprocess 类使启动命令变得容易,但我需要一些额外的功能。我想在使用我的 wxPython GUI 时摆脱命令提示符,但我仍然需要一种方法来显示 exp/imp 命令的输出。

我已经尝试过这两种方法:

command = "exp userid=user/pwd@nsn file=dump.dmp"

process = subprocess.Popen(command, stdout=subprocess.PIPE)
output = process.communicate()[0]

process = subprocess.Popen(command, stdout=subprocess.PIPE)
process.wait()
output = process.stdout.read()

通过其中一种方法(忘了哪一种),我确实得到了 exp/imp 的输出,但只有在命令完成之后,这对我来说毫无价值,因为在这些可能长时间运行的操作期间我需要经常更新。并且 sqlplus 提出了更多问题,因为 sqlplus 在发生错误时主要需要一些输入。当发生这种情况时,python 等待进程完成但用户看不到提示,所以你不知道要等待多长时间或做什么......

我想要的是一个包装器,它输出我在标准命令行上可以看到的所有内容。我想将它记录到一个文件中并在 wxPython 控件中显示它。

我还尝试了此页面中的代码: http: //code.activestate.com/recipes/440554/ 但这也无法读取输出。此答案中的 OutputWrapper 也不起作用:How can I capture all exceptions from a wxPython application?

任何帮助,将不胜感激!

编辑:
子进程似乎没有刷新它们的输出。我已经用 .readline() 试过了。
我的工具必须在 windows 和 unix 上运行,所以如果没有 windows 版本,pexpect 是没有解决方案的。并且使用 cx_oracle 将是极端的矫枉过正,因为我将不得不重建 exp、imp 和 sqlplus 的整个功能。

4

4 回答 4

1

解决方案是为您的命令使用列表

command = ["exp", "userid=user/pwd@nsn", "file=dump.dmp"]
process = subprocess.Popen(command, stdout=subprocess.PIPE)

然后你逐行阅读 process.stdout :

line = process.stdout.readline()

这样,您无需等待即可更新 GUI。如果您正在运行的子进程 (exp) 刷新输出。输出可能被缓冲,然后在输出缓冲区已满之前您将看不到任何内容。如果是这种情况,那么您可能不走运。

于 2009-02-10T10:59:05.980 回答
1

如果您使用的是 Linux,请查看pexpect。它完全符合您的要求。

如果您需要在 Windows 上工作,也许您应该硬着头皮使用 Python 绑定到 Oracle,例如cx_Oracle,而不是通过subprocess.

于 2009-02-10T11:51:25.510 回答
0

这些解决方案是否也能够捕获标准错误?我看到你上面有 stdout= 选项。您如何确保也获得 stderr ?另一个问题是有没有办法使用 import logging/import logging.handlers 来捕获命令 stdout/stderr。能够在格式化程序/旋转器等中使用带有其构建的记录器会很有趣。

于 2009-02-20T13:49:28.597 回答
-1

尝试这个:

import subprocess

command = "ping google.com"

process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
output = process.stdout
while 1:
    print output.readline(),
于 2009-02-10T10:55:30.683 回答