Python subprocess.Popen()后跟time.sleep

时间:2014-01-05 14:23:44

标签: python subprocess popen

我想创建一个python脚本,将TEX文件转换为PDF,然后使用我的文档查看器打开输出文件。

我首先尝试了以下内容:

import subprocess
subprocess.Popen(['xelatex', '--output-directory=Alunos/', 'Alunos/' + aluno + '_pratica.tex'], shell=False,  stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
subprocess.Popen(['gnome-open', 'Alunos/'+aluno+'_pratica.pdf'], shell=False)

这样,从TEX到PDF的转换可以正常工作,但是,由于需要一些时间,因此在创建输出文件之前执行第二个命令(使用Document Viewer打开文件)。

所以,我尝试让程序在执行第二个命令之前等待几秒钟。这就是我所做的:

import subprocess
import time
subprocess.Popen(['xelatex', '--output-directory=Alunos/', 'Alunos/' + aluno + '_pratica.tex'], shell=False,  stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
time.sleep(10)
subprocess.Popen(['gnome-open', 'Alunos/'+aluno+'_pratica.pdf'], shell=False)

但是,当我这样做时,不会创建输出PDF文件。我不明白为什么。唯一的变化是time.sleep命令。为什么它会影响Popen过程? 有人能给我一些帮助吗?

编辑:

我遵循了Faust和Paulo Bu的建议,在这两种情况下结果都是一样的。

当我运行此命令时......

subprocess.call('xelatex --output-directory=Alunos/ Alunos/{}_pratica.tex'.format(aluno), shell=True)

......或者......

p = subprocess.Popen(['xelatex', '--output-directory=Alunos/', 'Alunos/' + aluno + '_pratica.tex'], shell=False,  stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
p.wait()

... Xelatex程序已运行,但未进行转换。

奇怪的是,当我直接在shell中运行命令时......

$ xelatex --output-directory = Alunos / Alunos / name_pratica.tex

......转换效果很好。

这是我运行subprocess.call()命令时得到的结果:

$ python my_file.py 
Enter name:
name
This is XeTeX, Version 3.1415926-2.4-0.9998 (TeX Live 2012/Debian)
restricted \write18 enabled.
entering extended mode
(./Alunos/name_pratica.tex
LaTeX2e <2011/06/27>
Babel <v3.8m> and hyphenation patterns for english, dumylang, nohyphenation, loaded.
)
*

当我直接在shell中编写命令时,输出是相同的,但它会自动跟随转换。 有谁知道为什么会这样发生?

PS:抱歉结构不好。我不知道如何正确发布shell输出。

2 个答案:

答案 0 :(得分:1)

如果您需要等待程序终止并且您对其输出不感兴趣,则应使用subprocess.call

import subprocess
subprocess.call(['xelatex', '--output-directory=Alunos/', 'Alunos/{}_pratica.tex'.format(aluno)])
subprocess.call([('gnome-open', 'Alunos/{}_pratica.pdf'.format(aluno)])

编辑:

当您必须命名变量或函数时,使用英语通常也是一件好事。

答案 1 :(得分:0)

如果xelatex命令在shell中有效,但在从Python调用时失败,那么{C}可能会在Python代码中阻止输出xelatex。尽管将stdout / stderr设置为PIPE,但您不会读取管道。在我的机器上,管道缓冲区是64KB,因此如果xelatex输出大小小于它,则它不应该阻塞。

您可以将输出重定向到os.devnull

import os
import webbrowser
from subprocess import STDOUT, check_call

try:
    from subprocess import DEVNULL # py3k
except ImportError:
    DEVNULL = open(os.devnull, 'w+b')

basename = aluno + '_pratica'
output_dir = 'Alunos'
root = os.path.join(output_dir, basename)
check_call(['xelatex', '--output-directory', output_dir, root+'.tex'],
           stdin=DEVNULL, stdout=DEVNULL, stderr=STDOUT)
webbrowser.open(root+'.pdf')

check_call用于等待xelatex并在出错时引发异常。