检查shell下的进程停止

时间:2012-01-31 21:58:10

标签: python windows shell process wkhtmltopdf

这是Windows环境下的python程序的一部分。我正在尝试执行以下操作: 从一个HTML,我想创建一个PDF,然后打开它:

    #create the pdf
    os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name))
    #open the current pdf
    os.system("start %s%s" %(output_directory, pdf_document_name))

问题是有时创建pdf的脚本速度较慢,所以我从终端收到错误,说没有这样名字的文件。
我想问一下,只有在创建成功并完成时才能打开pdf。我知道如何通过调用time.sleep()来做到这一点,但我认为这不太专业。
非常感谢,你D

2 个答案:

答案 0 :(得分:2)

无论您使用哪种方法执行shell命令(subprocess,os.system等),都应该在尝试打开文件之前验证文件是否存在。然后,您可以在尝试打开延迟之前将延迟设置为File-Exists-Else-Wait-Repeat循环。 您可以使用os.path.exists()

执行此操作
#create the pdf
os.system("start wkhtmltopdf.exe result.html %s%s" %(output_directory, pdf_document_name))

#loop until pdf exists, but add some timer to avoid endless repetition
maxiterations = 60
exists = False
for i in range(maxiterations):
    if os.path.exists(os.path.join(output_directory, pdf_document_name)):
        exists = True
        break;
    time.sleep(1)
#open the current pdf
if exists:
    os.system("start %s%s" %(output_directory, pdf_document_name))
else:
    print 'Could not find file %s to open' % os.path.join(output_directory, pdf_document_name)

另一个需要注意的是,这会引入一个安全漏洞,因为文件可能会在您验证它并打开它之间传递的时间内发生变化(例如,它可能已被恶意代码替换)。 处理此问题的另一种方法是尝试在try ... except ...块中打开它,但这并不能真正解决安全问题(文件可能在创建和尝试打开它之间被替换)

答案 1 :(得分:1)

我认为使用time.sleep()并不存在“不专业”的问题。实际上,对于你建议的解决方案,最不专业(或者至少是Pythonic)的事情是使用os.system。请改用subprocess模块中的函数。在这种情况下,您可以使用subprocess.call,等待程序在继续之前退出。例如,如果您在交互式解释器中执行此操作:

import subprocess, shlex
subprocess.call(shlex.split('sleep 5'))

你会看到Python在继续之前等待五秒钟sleep完成。 (然后返回退出代码。)Shlex只需将命令行拆分为参数列表,供callsubprocess提供的其他几个函数和类使用。

>>> shlex.split("start wkhtmltopdf.exe result.html %s%s" %('out_dir/', 'pdf_name'))
['start', 'wkhtmltopdf.exe', 'result.html', 'out_dir/pdf_name']