Pipe support
pdfTeX support pipes since version 1.40.0 (released 2007-01-01). From NEWS:
shell escape: if the first character of a filename for \openin, \openout
\input is a pipe symbol (|), the filename is assumed to be a request for a
pipe to a command line that is given in the rest of the filename
The feature is enabled in different ways depending on the TeX distribution:
- TeX Live: --shell-restricted (default) allows some few commands to be called (e.g. kpsewhich, makeindex. See variable
shell_escape_commands in texmf.cnf. Otherwise
full shell escape rights are needed. They can be set by option `--shell-escape'.
- MiKTeX: Pipe support is activated by `--enable-pipes'. Shell escape options do not
affect pipes.
Package catchfile (for plain and LaTeX formats) will add \CatchPipeDef and \CatchPipeEdef in version 2012/07/30 v1.6 to support pdfTeX's pipe feature.
LuaTeX does not have the same pipe feature of pdfTeX, because it has the Lua function io.popen that can be used for that purpose.
Pacakge pdftexcmds provides \pdf@pipe as wrapper for convenience.
XeTeX: I could not get pipes running and working neither in TL2011/Linux nor MiKTeX 2.9.
In the latter case I could only catch an empty line instead of the intended program output.
OS independent command line
Nowadays TeX distributions often include LuaTeX with its program texlua.
For example, the following Lua script prints the time in seconds since 1970-01-01:
if os.gettimeofday then
print(os.gettimeofday())
else
print(os.date("%s"))
end
Then the command call
texlua gettimeofday.lua
prints 1343650327.0485, for example.
However if gettimeofday.lua is not in the current directory, texlua will not find
it, because its kpathsea module is not active. At least TL and MiKTeX provide
kpsewhich for finding the file.
Example for pdfTeX and the new version (2012/07/30 v1.6) of package catchfile:
\CatchPipeEdef\ScriptGettimeofday{kpsewhich gettimeofday.lua}{\endlinechar=-1}
\CatchPipeEef\CurrentTime{texlua \ScriptGettimeofday}{\endlinechar=-1}
Macro \CurrentTime contains the result. Or with low level commands (with e-TeX),
it is something like:
\begingroup
\everyeof{\noexpand}%
\endlinechar=-1 %
\edef\file{\input |"kpsewhich gettimeofday.lua"}
\xdef\CurrentTime{\input |"texlua \file"}
% Use \@@input in LaTeX instead of the redefined \input
\endgroup
PS: The new version of package catchfile: catchfile-1.6.pdf
(The .dtx file is attached to the PDF. Run tex on catchfile.dtx to
unpack the package.)
Answer to Bruno's comment:
If pipes are not available, then the ordinary write18 feature can be used.
However there are many downsides:
- Slower (file writing, searching and reading)
- The wrong file might be found. That can be tested by writing some
random bytes in a file with the
write18 process and reading them
back and checking, whether bytes are the same.
- The solution cannot be made expandable.
- More things that can break: File is not written (e.g. readonly directory),
cannot be found, the wrong file is found, …
- Unique temporary file names needed to avoid conflicts in multi-user systems or multiple
processes at the same time.
- Cleanup: Delete commands are again OS dependent (
rm in Unix, del in Windows).
or the temporary files remain.
|syntax work even on Windows when using MiKTeX? I have a feeling its TeX Live-specific. – Joseph Wright Jul 30 '12 at 05:54|syntax on miktex if you use the option--enable-pipes.--shell-escapeis not needed. But the behaviour is inconsistent throught the engines:\input "|date /t"works fine with pdflatex, gives with lualatex an error, and no error but also no output with xelatex. – Ulrike Fischer Jul 30 '12 at 07:37