在Mac上通过Python子进程运行pdflatex

4 投票
2 回答
5464 浏览
提问于 2025-04-16 07:22

我正在尝试从Python 2.4.4的子进程中运行pdflatex来处理一个.tex文件(在Mac上):

import subprocess
subprocess.Popen(["pdflatex", "fullpathtotexfile"], shell=True)

但是这样做实际上没有任何效果。不过,我可以在终端中直接运行“pdflatex fullpathtotexfile”,这样就能顺利生成一个pdf文件。我到底漏掉了什么呢?

[编辑]

根据其中一个回答的建议,我尝试了:

return_value = subprocess.call(['pdflatex', '/Users/Benjamin/Desktop/directory/ON.tex'], shell =False)

但是这个方法失败了,出现了:

Traceback (most recent call last):
  File "/Users/Benjamin/Desktop/directory/generate_tex_files_v3.py", line 285, in -toplevel-
    return_value = subprocess.call(['pdflatex', '/Users/Benjamin/Desktop/directory/ON.tex'], shell =False)
  File "/Library/Frameworks/Python.framework/Versions/2.4//lib/python2.4/subprocess.py", line 413, in call
    return Popen(*args, **kwargs).wait()
  File "/Library/Frameworks/Python.framework/Versions/2.4//lib/python2.4/subprocess.py", line 543, in __init__
    errread, errwrite)
  File "/Library/Frameworks/Python.framework/Versions/2.4//lib/python2.4/subprocess.py", line 975, in _execute_child
    raise child_exception
OSError: [Errno 2] No such file or directory

文件确实存在,我可以在终端中运行pdflatex /Users/Benjamin/Desktop/directory/ON.tex。需要注意的是,pdflatex会发出很多警告……但这应该不影响结果,而且这个方法也出现了同样的错误:

return_value = subprocess.call(['pdflatex', '-interaction=batchmode', '/Users/Benjamin/Desktop/directory/ON.tex'], shell =False)

2 个回答

1

你可能想要以下两种选择:

output = Popen(["pdflatex", "fullpathtotexfile"], stdout=PIPE).communicate()[0]
print output

或者

p = subprocess.Popen(["pdflatex" + " fullpathtotexfile"], shell=True)
sts = os.waitpid(p.pid, 0)[1]

(这段内容是从这个 subprocess 文档页面 中直接拿来的)。

5

可以使用一个很方便的函数,叫做 subprocess.call

在这里你不需要用到 Popen,用 call 就足够了。

比如说:

>>> import subprocess
>>> return_value = subprocess.call(['pdflatex', 'textfile'], shell=False) # shell should be set to False

如果调用成功,return_value 会被设置为 0,否则就是 1。

使用 Popen 通常是为了你想保存输出的情况。比如说,你想用命令 uname 来检查内核版本,并把结果存到某个变量里:

>>> process = subprocess.Popen(['uname', '-r'], shell=False, stdout=subprocess.PIPE)
>>> output = process.communicate()[0]
>>> output
'2.6.35-22-generic\n'

再说一次,千万不要设置 shell=True

撰写回答