7

根据 Python 文档,subprocess.call应该阻塞并等待子进程完成。在这段代码中,我试图通过调用命令行将几个xls文件转换为新格式。Libreoffice我假设对子进程调用的调用是阻塞的,但似乎我需要在每次调用后添加一个人为的延迟,否则我会错过目录中的几个文件out

我究竟做错了什么?为什么我需要延迟?

from subprocess import call

for i in range(0,len(sorted_files)):
            args = ['libreoffice', '-headless', '-convert-to',
                    'xls', "%s/%s.xls" %(sorted_files[i]['filename'],sorted_files[i]['filename']), '-outdir', 'out']
            call(args)
            var = raw_input("Enter something: ") # if comment this line I dont get all the files in out directory

编辑通过下面的评论可能很难找到答案。我用于unoconv文档转换,它是阻塞的,并且易于从脚本中使用。

4

3 回答 3

5

可能libreoffice作为某种守护进程/中间进程实现的。“守护进程”将(实际上是1)解析命令行,然后将工作转移到其他进程,可能会将它们分离,以便它可以立即退出。(基于文档-invisible中的选项,我强烈怀疑您确实是这种情况)。

如果是这种情况,那么您subprocess.call确实会按照宣传的方式去做——它会等待守护进程完成,然后再继续。但是,它并不能满足您的要求,即等待所有工作完成。在这种情况下,您唯一的选择是查看守护程序是否有-wait选项或类似选项。


1很可能我们这里没有真正的守护进程,只有行为类似的东西。查看abernert 的评论

于 2013-04-29T18:46:33.600 回答
3

问题是soffice命令行工具(它libreoffice要么只是一个链接,要么是进一步的包装)只是真实程序的“控制器” soffice.bin。它找到一个运行副本soffice.bin和/或创建,告诉它做一些工作,然后退出。

所以,call正在做完全正确的事情:它等待libreoffice退出。

但是你不想等待libreoffice退出,你想等待soffice.bin完成libreoffice要求它做的工作。

看起来你想要做的事情是不可能直接做的。但可以间接做。

文档说无头模式:

…允许在没有用户界面的情况下使用应用程序。

当应用程序由外部客户端通过 API 控制时,可以使用这种特殊模式。

换句话说,应用程序在运行一些 UNO 字符串/进行一些转换/您在命令行上指定的任何其他内容后都不会退出,它会等待来自外部的更多 UNO 命令,而启动器只会在它发送后立即运行应用程序的相应命令。


您可能必须直接使用上述外部控制 API (UNO)。

有关基础知识,请参阅Scripting LibreOffice(尽管有关内部脚本的信息比外部更多),有关详细信息和示例,请参阅API 文档

但可能还有一个更简单的答案:unoconv这是一个使用 UNO API 编写的简单命令行工具,它完全可以满足您的需求。如有必要,它会启动 LibreOffice,向其发送一些命令,等待结果,然后退出。因此,如果您只使用unoconv而不是libreoffice,call就是您所需要的。

另请注意,它unoconv是用 Python 编写的,旨在用作模块。如果您只是import这样做,您可以编写自己的(更简单且特定于用例的)代码来替换“主入口”代码,并且根本不使用subprocess。(或者,当然,您可以拆开模块并自己使用相关代码,或者只是将其用作非常好的示例代码,以便在 Python 中使用 UNO。)

此外,unoconv上面链接的页面列出了各种其他类似的工具,有些可以通过 UNO 工作,有些不能,所以如果它不适合您,请尝试其他工具。


如果没有其他工作,您可以考虑,例如,创建一个哨兵文件并使用文件系统监视,这样至少您将能够准确地检测到它何时完成其工作,而不必猜测超时。但这是一个真正的最后解决方法,在消除所有其他选项之前,您甚至不应该考虑。

于 2013-04-29T19:05:32.653 回答
0

如果 libreoffice 正在使用@mgilson 提到的中介(守护进程),那么一种解决方案是找出它正在调用的程序,然后自己直接调用它。

于 2013-04-29T18:51:24.013 回答