4

I'm trying to run pdflatex on a .tex file from a Python 2.4.4. subprocess (on a mac):

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

which effectively does nothing. However, I can run "pdflatex fullpathtotexfile" in the terminal without issues, generating a pdf. What am I missing?

[EDIT] As suggested in one of the answers, I tried:

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

which fails with:

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

The file does exist and I am able to run pdflatex /Users/Benjamin/Desktop/directory/ON.tex in the Terminal. Note that pdflatex does throw a good number of warnings... but that shouldn't matter, and this also gives the same error:

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

2 Answers2

5

Use the convenience function, subprocess.call

You don't need to use Popen here, call should suffice.

For example:

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

If the call was successful, return_value will be set to 0, or else 1.

Usage of Popen is typically for cases when you want the store the output. For example, you want to check for the kernel release using the command uname and store it in some variable:

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

Again, never set shell=True.

user225312
  • 126,773
  • 69
  • 172
  • 181
  • 1
    note: `shell=False` is the default (you don't need to pass it explicitly) – jfs Nov 02 '15 at 13:02
  • great post. It helped me a lot for months, but now I have a new issue, I can't specify the output dir, any clue about how to do it? https://tex.stackexchange.com/questions/468278/how-to-use-output-directory-with-python-subprocess-call-and-macos – DaniPaniz Jan 02 '19 at 16:42
1

You might want either:

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

or

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

(Shamelessly ripped from this subprocess doc page section ).

mjhm
  • 16,497
  • 10
  • 44
  • 55
  • 1
    For 1) I needed stdout=subprocess.PIPE, I think, but it still gives the error "OSError: [Errno 2] No such file or directory" although there is and it works in the terminal. For 2), nothing happens when I run it, although sts is set. – Benjamin Nov 20 '10 at 04:17
  • So its complaining that it can't find "pdflatex". Maybe it's an alias in the shell. Perhaps you can try the full path to pdflatex. – mjhm Nov 20 '10 at 05:11
  • Bingo, giving the full path worked, even though it is an alias to pdftex. Although that solves my problem, I prefer sukhbir's syntax. Thanks for your help. – Benjamin Nov 20 '10 at 05:54
  • On Python 3.5+, use `subprocess.run(["pdflatex", "fullpathtotexfile.tex"], stdout=subprocess.PIPE)`. – weiji14 Nov 24 '19 at 21:40