【问题标题】:Logging output of external program with (wx)python使用 (wx)python 记录外部程序的输出
【发布时间】:2010-10-06 14:41:59
【问题描述】:

我正在编写一个 GUI,用于使用 oracle exp/imp 命令并通过 sqlplus 启动 sql-scripts。 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 的整个功能。

【问题讨论】:

  • 为什么是什么?不知道你在说什么……

标签: python oracle wxpython sqlplus


【解决方案1】:

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

【讨论】:

【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    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) 刷新输出。输出可能是缓冲的,那么在输出缓冲区满之前你什么都看不到。如果是这种情况,那么您可能不走运。

    【讨论】:

      【解决方案4】:

      试试这个:

      import subprocess
      
      command = "ping google.com"
      
      process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
      output = process.stdout
      while 1:
          print output.readline(),
      

      【讨论】:

      • 不要使用 shell=True。它将执行shell,而shell将用于执行命令,这是另一个子进程,没有任何好处。它碍事,与问题无关。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-28
      • 2017-08-08
      • 1970-01-01
      相关资源
      最近更新 更多