TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

What are \immediate and \write18 and how does one use them? I'd like some examples spanning from basic to advanced scenarios.

share|improve this question
up vote 56 down vote accepted

Both \immediate and \write are TeX primitives. The \write operation is used to write to a file stream. Like many other things in TeX, file streams are accessed by number (although usually real files are given symbolic names to make life easier). Stream 18 is 'special' as it is not a file at all: instead, it is a way of sending commands to the operating system (shell).

As TeX is a typesetting system, the standard behaviour of \write is to wait until a page is being shipped out before doing anything. That is what you want if the write operation needs things like page numbers. However, there are occasions when you want to write now, which is what \immediate forces. So


means 'send <stuff> to the operating system for execution now'.

There are security issues with allowing arbitrary commands inside a TeX file, and so the standard settings in both TeX Live and MiKTeX turn off full access to \write18. You can turn it on, if you want full access, using latex --shell-escape (or similar) in place of just latex.

As to examples of use, one pretty useful one is to automatically run BibTeX at the start of each LaTeX run by including as the first line

\immediate\write18{bibtex8 --wolfgang \jobname}

The \write operation carries out expansion, and so \jobname here will be converted into the name of the current TeX file.

Recent versions of TeX Live and MiKTeX have a 'restricted \write18' concept which allows a small number of commands to work in \write18 even if --shell-escape is not given. This list is pretty short and features only 'safe' commands (where arbitrary file operations have deliberately been disabled).

share|improve this answer
@Joseph: Can we insert the output of an external application into (La)TeX document immediately without using a temporary file? – xport Jun 11 '11 at 7:23
@Joseph: For example: The external application produces some messages on a console window. – xport Jun 11 '11 at 7:25
@Joseph You might mention the "combined" action of executing a system command and getting the output into TeX by \input|"<command>" (where \input is the TeX primitive, \@@input in LaTeX). – egreg Jun 11 '11 at 9:39
(How) Is it possible to write something to a file? Lets say I’d like to write the line mycmd used with #1 and #2 with each call of \mycmd{#1}{#2} to a file named mycmd.log. – Tobi Jun 12 '11 at 9:26
@morbusg In texmf.cnf, for me inside /usr/local/texlive/2012/texmf/web2c/texmf.cnf (second one from kpsewhich texmf.cnf --all). – Joseph Wright Jan 17 '13 at 11:36

PdfTeX has another way to execute system commands which is useful when we need to include the command's output in our document:

\input|"ls xyz.*"

will include the output of the system command enclosed in double quotes. The command line option --shell-escape (or --enable-write18 for MiKTeX) must be given, of course.

When this is used in LaTeX it's still necessary to use the primitive \input, so the construction should be

\@@input|"ls xyz.*"

This is equivalent to the more complicated

\immediate\write18{ls xyz.* > temp.dat}

but doesn't require a temporary file. Unfortunately, older versions of XeTeX and LuaTeX don't know about this syntax.

share|improve this answer
Update: in TeX Live 2013 the syntax \input|"command" is supported also by XeTeX and LuaTeX. – egreg Oct 23 '13 at 22:55
That doesn't work. I get the error: runpopen command not allowed: echo ! I can't find file `"|echo 42"'. l.5 \@@input|"echo 42" – Peter Flynn Apr 8 at 14:07
@PeterFlynn You have to run with -shell-escape, as mentioned in the answer. – egreg Apr 8 at 14:14
I thought I had configured LaTeX to do that in the config file, as my log output said so, but apparently that doesn't work — you do indeed have to specify --shell-escape explicitly. Weird. – Peter Flynn Apr 9 at 21:58

The explanations of Joseph are always good. I give this answer only to show an example: elephant.ps is a picture you can find in the latex companion examples.

% with pdflatex

\immediate\write18{pstopdf elephant.ps}% to get elephant.pdf

\immediate\write18is very useful to work with gnuplot (see gnuplottex's source), maxima, xcas and bc for examples.

share|improve this answer
The package epstopdf does that trick automatically (TeX Live 2010 is required, I don't know about MiKTeX 2.9). The commands that can be run without enabling shell-escape are repstopdf (a restricted form of epstopdf, bibtex, bibtex8, kpsewhich and makeindex. – egreg Jun 11 '11 at 9:33
@egreg Yes I know but like you say, TL 2010 is required and a lot of people works with TL 2009. This is only an example and we can use other commands with shell-escape like bc. – Alain Matthes Jun 11 '11 at 9:59
@egreg: I think the point here was the example, rather than necessarily saying its useful to everyone. I'd also note that you can use epstopdf quite happily with older TeX Live/MiKTeX systems, it's just that you need to enable \write18. – Joseph Wright Jun 11 '11 at 14:13
@AlainMatthes Do we need to specify the full path to the file for the command to work? I am having trouble with pdfcrop. I am running the command: \immediate\write18{pdfcrop file.pdf} at the end of my document but I get no output. – Cebri Jun 29 at 2:02

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.