重定向 Python 中的 C 库标准输出消息
Redirect c library stdout messages in Python
我在 Python 2.7 中使用 Gtk+ 3.10.8 运行 在 Linux Mint 17.1 上有一个 GUI 应用程序。
该应用程序使用 libvlc 库的 python 绑定来嵌入视频播放器。 libvlc 库使用 libav 进行视频处理。
我的问题是 libav 非常冗长并且会不断生成警告流,而 libvlc 不提供任何机制来改变冗长或抑制它。
显然,可以通过 运行 python 脚本关闭噪音(例如):
$ ./myprogram.py &> /dev/null
我希望能够在程序中以编程方式实现相同的效果。我很乐意简单地禁止从外部库到 stdout 的所有访问,但最终捕获该输出并实现一些日志记录会更好。
我能找到的关于这个主题的所有示例都假定对外部进程有更直接的控制,即将其声明为子进程。当我无法从我的 Python 代码直接访问相关的实际库 (libav) 时,还有另一种方法吗?
编辑:
感谢大家的帮助,正确答案可以在:
Python version of freopen(),回答 #3。
您只需确保您的代码不是 运行 来自 IDE 的代码,它会以任何方式干扰标准输出。 Interactive IDEs 倾向于这样做,并且会抛出如下错误:
AttributeError: FileWrapper instance has no attribute 'fileno'
最简单的解决方案可能是关闭 stdout
并打开 /dev/null
作为新的 stdout
。这应该有望关闭用于 stdout
的底层文件描述符,这意味着下一个打开的文件将重用该描述符。
如果您可以从您的应用程序调用 "C" 库函数,您可以使用 freopen()
将标准输出和标准错误流从您的进程重定向到您自己的日志文件或 /dev/null
我想。
我这样做的方法是:
FILE *stdout = fdopen(1, "w");
FILE *myout = freopen("out.log", "w", stdout);
类似于 stderr,使用 1
的 2
实例作为文件描述符参数:
FILE *stderr = fdopen(2, "w");
FILE *myerr = freopen("err.log", "w", stdout);
我在我的 Java LibVLC 绑定中正是这样做的。
我在 Python 2.7 中使用 Gtk+ 3.10.8 运行 在 Linux Mint 17.1 上有一个 GUI 应用程序。
该应用程序使用 libvlc 库的 python 绑定来嵌入视频播放器。 libvlc 库使用 libav 进行视频处理。
我的问题是 libav 非常冗长并且会不断生成警告流,而 libvlc 不提供任何机制来改变冗长或抑制它。
显然,可以通过 运行 python 脚本关闭噪音(例如):
$ ./myprogram.py &> /dev/null
我希望能够在程序中以编程方式实现相同的效果。我很乐意简单地禁止从外部库到 stdout 的所有访问,但最终捕获该输出并实现一些日志记录会更好。
我能找到的关于这个主题的所有示例都假定对外部进程有更直接的控制,即将其声明为子进程。当我无法从我的 Python 代码直接访问相关的实际库 (libav) 时,还有另一种方法吗?
编辑: 感谢大家的帮助,正确答案可以在: Python version of freopen(),回答 #3。
您只需确保您的代码不是 运行 来自 IDE 的代码,它会以任何方式干扰标准输出。 Interactive IDEs 倾向于这样做,并且会抛出如下错误:
AttributeError: FileWrapper instance has no attribute 'fileno'
最简单的解决方案可能是关闭 stdout
并打开 /dev/null
作为新的 stdout
。这应该有望关闭用于 stdout
的底层文件描述符,这意味着下一个打开的文件将重用该描述符。
如果您可以从您的应用程序调用 "C" 库函数,您可以使用 freopen()
将标准输出和标准错误流从您的进程重定向到您自己的日志文件或 /dev/null
我想。
我这样做的方法是:
FILE *stdout = fdopen(1, "w");
FILE *myout = freopen("out.log", "w", stdout);
类似于 stderr,使用 1
的 2
实例作为文件描述符参数:
FILE *stderr = fdopen(2, "w");
FILE *myerr = freopen("err.log", "w", stdout);
我在我的 Java LibVLC 绑定中正是这样做的。