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
\immediate\write18{<stuff>}
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).
Just concatenate the echo
commands:
\documentclass{article}
\begin{document}
\immediate\write18{%
echo "" > foobar.txt;
echo "" >> foobar.txt;
echo "--------" >> foobar.txt;
echo "Foo: foo" >> foobar.txt;
echo "Foo: foo" >> foobar.txt;
echo "Bar: bar" >> foobar.txt
}
\end{document}
If the noclobber
variable is set, the shell will refuse to overwrite an existing file with an output redirection command. So if the variable is set in the environment of the called command shell, the first echo "" > foobar.txt
will not succeed.
However the same result will be obtained with the standard stream writing:
\newwrite\foobar
\immediate\openout\foobar=foobar.txt
\immediate\write\foobar{}
\immediate\write\foobar{}
\immediate\write\foobar{--------}
\immediate\write\foobar{Foo: foo}
\immediate\write\foobar{Foo: foo}
\immediate\write\foobar{Foo: bar}
\immediate\closeout\foobar
Best Answer
One approach is to replicate what latexmk does in determining the number of pdflatex iterations required, and replicate it.
However, as commented by others, the easiest is indeed to rely of storing the status on a file and read it during execution.
Since I never clean the generated files, the approach I've followed is to check for the existence of the .fdb_latexmk (generated at the very end of running latexmk) and if it exists delete it and run the scripts. If it does not exist then do nothing.
Not the most elegant answer but does work indeed.