\write18
¶Synopsis:
\write18{shell_command}
Issue a command to the operating system shell. The operating system runs the command and LaTeX’s execution is blocked until that finishes.
This sequence (on Unix)
\usepackage{graphicx} % in preamble ... \newcommand{\fignum}{1} \immediate\write18{cd pix && asy figure\fignum} \includegraphics{pix/figure\fignum.pdf}
will run Asymptote (the asy
program) on pix/figure1.asy,
so that the document can later read in the resulting graphic
(see \includegraphics
). Like any \write
, here LaTeX
expands macros in shell_command so that \fignum
is
replaced by ‘1’.
Another example is that you can automatically run BibTeX at the start
of each LaTeX run (see Using BibTeX) by including
\immediate\write18{bibtex8 \jobname}
as the first line of the
file. Note that \jobname
expands to the basename of the root
file unless the --jobname
option is passed on the command line,
in which case this is the option argument.
You sometimes need to do a multi-step process to get the information
that you want. This will insert into the input a list of all PDF files
in the current directory (but see texosquery
below):
\immediate\write18{ls *.pdf > tmp.dat} \input{tmp.dat}
The standard behavior of any \write
is to wait until a page is
being shipped out before expanding the macros or writing to the stream
(see \write
). But sometimes you want it done now. For this, use
\immediate\write18{shell_command}
.
There are obvious security issues with allowing system commands inside
a LaTeX file. If you download a file off the net and it contains
commands to delete all your files then you would be unhappy. The
standard settings in modern distributions turn off full shell
access. You can turn it on, if you are sure the shell commands are
safe, by compiling with latex --enable-write18 filename
(see Command line options). (The --shell-escape
option is
a synonym, in TeX Live.)
In the place of full shell access, modern distributions by default use
a restricted version that allows some commands to work, such as those
that run Metafont to generate missing fonts, even if you do not use
the enable-write18
option. By default this list of allowed
commands is short and features only commands that are under the
control of the distribution maintainers (see Command line options).
The shell_command text is always passed to /bin/sh on
Unix-like operating systems, and the DOS command interpreter
cmd.exe on Windows. Any different shell set by the user, and
the SHELL
environment variable, is ignored.
If what you need is system information, such as the operating system
name, locale information, or directory contents, take a look at the
texosquery
package, which provides a convenient and secure
interface for this, unlike the above examples using the raw
\write18
: https://ctan.org/pkg/texosquery.
LaTeX provides a package shellesc
on top of the primitive
\write18
command. Its primary purpose is to provide a command
\ShellEscape
which works identically on all TeX engines;
LuaTeX intentionally did not retain \write18
as a way to
invoke a shell command, so some engine-specific code is needed. The
shellesc
package also provides a command
\DelayedShellEscape
, executed at \output
time, for the
same reason.