我正在编写一个使用oracle exp / imp命令并通过sqlplus启动sql-scripts的GUI。子流程类可以轻松启动命令,但我需要一些额外的功能。我想在使用我的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的整个功能。
答案 0 :(得分:1)
解决方案是使用命令列表
command = ["exp", "userid=user/pwd@nsn", "file=dump.dmp"]
process = subprocess.Popen(command, stdout=subprocess.PIPE)
然后逐行读取process.stdout:
line = process.stdout.readline()
这样您就可以无需等待即可更新GUI。 IF 您正在运行的子进程(exp)刷新输出。输出可能是缓冲的,那么在输出缓冲区已满之前您将看不到任何内容。如果是这种情况,那么你可能运气不好。
答案 1 :(得分:1)
如果您使用的是Linux,请查看pexpect。它完全符合您的要求。
如果您需要在Windows上工作,也许您应该咬紧牙关并使用Python绑定到Oracle,例如cx_Oracle,而不是通过subprocess
运行CL内容。
答案 2 :(得分:0)
这些解决方案是否也能捕获stderr?我看到你上面有stdout =选项。你如何确保获得stderr?另一个问题是有没有办法使用import logging / import logging.handlers来捕获命令stdout / stderr。能够将记录器与其格式化器/旋转器等中的构建一起使用将是有趣的。
答案 3 :(得分:-1)
试试这个:
import subprocess
command = "ping google.com"
process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
output = process.stdout
while 1:
print output.readline(),