Search code examples
pythonoperating-systemsubprocesslatex

Why is there no .tex file created by my script?


I tried to run this script (from https://tug.org/tug2019/slides/slides-ziegenhagen-python.pdf, on page 12)

import subprocess, os

with open("sometexfile.tex","w") as file:
  file.write("\\documentclass{article}\n")
  file.write("\\begin{document}\n")
  file.write("Hello Palo Alto!\n")
  file.write("\\end{document}\n")


x = subprocess.call("pdflatex sometexfile.tex")
if x != 0:
  print("Exit-code not 0, please check result!")
else:
  os.system("start sometexfile.pdf")

but it gives my the following error :

line 39, in <module>
    x = subprocess.call("pdflatex sometexfile.tex")
  File "/usr/lib/python3.10/subprocess.py", line 345, in call
    with Popen(*popenargs, **kwargs) as p:
  File "/usr/lib/python3.10/subprocess.py", line 971, in __init__
    self._execute_child(args, executable, preexec_fn, close_fds,
  File "/usr/lib/python3.10/subprocess.py", line 1863, in _execute_child
    raise child_exception_type(errno_num, err_msg, err_filename)
FileNotFoundError: [Errno 2] No such file or directory: 'pdflatex sometexfile.tex'

Solution

  • There are two ways, one with shell=True and one setted to False (noticed that is OS dependent).

    The shell argument (which defaults to False) specifies whether to use the shell as the program to execute. If shell is True, it is recommended to pass args as a string rather than as a sequence.

    use the doc for further information concerning the OSs differences.

    Setting shell=True carries some security considerations. It's better to pass a command as list and not as a string

    cmd = "pdflatex sometexfile.tex".split()
    

    or for more complicated cases use the ad-hoc command shlex.split from the standard library.

    cmd = ["pdflatex", path_tex_file]
    
    cp = subprocess.run(cmd, shell=False)
    
    if cp.returncode != 0:
        print("Exit-code not 0, please check result!")
    

    Notice that the auxiliary files (aux, toc, ...)could be written in the other directory (depending where you run the code in your environment), check the options for pdflatex --help. An example could be

    # tell pdflatex to write the output at a specific directory
    path_dir = # your path
    cmd = ["pdflatex", "-output-directory", path_dir, path_tex_file]