Here is a self-answer, as I didn't find this info anywhere explicitly - \immediate\write18 seems to have a blocking behavior.
I used perl on Linux, with a for loop with a sleep inside as the test program; it turns out, it's a bit itchy to escape the linefeed \n as raw ASCII for the external shell command - so, one needs to be careful about that. Otherwise, the MWE below produces the following output, when Latex is called with -shell-escape:
$ pdflatex -shell-escape test.tex
This is pdfTeX, Version 3.1415926-2.3-1.40.12 (TeX Live 2011)
\write18 enabled.
entering extended mode
(./test.tex
LaTeX2e <2011/06/27>
Babel <v3.8m> and hyphenation patterns for english, dumylang, nohyphenation, lo
aded.
(/path/to/texlive/2011/texmf-dist/tex/latex/base/article.cls
Document Class: article 2007/10/19 v1.4h Standard LaTeX document class
(/path/to/texlive/2011/texmf-dist/tex/latex/base/size10.clo))
(./test.aux)
Check: outputting command:
echo 'for($ix=0;$ix<5;$ix++){ print("perl $ix \n");sleep 1;};' ; perl -e 'for(
$ix=0;$ix<5;$ix++){ print("perl $ix \n");sleep 1;};'
\LaTeX typeout: Before write18
for($ix=0;$ix<5;$ix++){ print("perl $ix
");sleep 1;};
perl 0
perl 1
perl 2
perl 3
perl 4
\LaTeX typeout: After write18
(./test.aux) )
No pages of output.
Transcript written on test.log.
Clearly, the \write18 waited for the perl code to execute first - before allowing Latex to continue onwards.
Here is the MWE, test.tex:
\documentclass{article}
\begin{document}
% http://tex.stackexchange.com/a/69294/2595
% must escape backslash like this, to have escaped linefeed
% character \n in \write18 output for the shell (raw ASCII)!
\begingroup
\catcode `~=11
\gdef\mytilde{~}
\catcode `\|=0
\catcode `\\=11
|gdef|LF{\n} % \LF becomes (ASCII) "\n" (verbatim char!)
|gdef|n{\n} % \n becomes (ASCII) "\n" (verbatim char!)
|gdef|ELF{\\n} % \ELF becomes (ASCII) "\\n" - escaped backslash for shell!
|endgroup
\edef\cmd{%
%echo 'for($ix=0;$ix<5;$ix++){ print("perl $ix \LF");sleep 1;};'
% below works, with a previous definition of linefeed (with
% non-escaped backslash) \n as macro; then linefeed char is verbatim
%echo 'for($ix=0;$ix<5;$ix++){ print("perl $ix \n");sleep 1;};'
% like this for escaped-backslash-linefeed to propagate through shell;
% the programs see escaped backslash then:
%echo 'for($ix=0;$ix<5;$ix++){ print("perl $ix \ELF");sleep 1;};' ;
%
% The proper one is with \n/\LF; don't forget `;` separators for bash
% (as latex will compact these in a single line anyway)
%
echo 'for($ix=0;$ix<5;$ix++){ print("perl $ix \n");sleep 1;};' ;
perl -e 'for($ix=0;$ix<5;$ix++){ print("perl $ix \n");sleep 1;};'
}
\typeout{%
Check: outputting command: ^^J
\cmd% OK
}
\typeout{^^J \LaTeX typeout: Before write18 ^^J}
\immediate\write18{%
\cmd% OK
}%
\typeout{^^J \LaTeX typeout: After write18 ^^J}
\end{document}
(La)TeXhas absolutely no support for multi-thread or multi-core setups. Anyway, in this specific case, how would you expect the asynchronous protocol to behave? The external command is supposed to have an impact on whatTeXdoes on the rest of the document... – T. Verron Jun 20 '14 at 07:08:)Cheers! – sdaau Jun 20 '14 at 07:29