I'm using \immediate\write18{./somescript.sh}
to execute my own shell script at the beginning of the latex compilation process. Is there a possibility to get the return value afterwards?
3 Answers
A very elementary approach using shell facilities:
Write the script execution state (either of the script itself or of the last command to an external file using >
redirection and then read this generated file to a \def\foomacro
.
\documentclass{book}
\newread\myscriptresult
\begin{document}
\immediate\write18{./myscript.sh; echo $? > scriptresult.txt}
\immediate\openin\myscriptresult=scriptresult.txt
\read\myscriptresult to \ScriptResult
\immediate\closein\myscriptresult
The result was \ScriptResult
\end{document}
myscript.sh
:
#!/bin/bash
ls -la
-
It works really nice, but only when use a filename with an extension, e.g.
result.txt
. Without this file extension, the latex compilation process stops, as nothing is read into\ScriptResult
and a comparison for an\ifnum
fails. I don't know, if the file extension is somehow mandatory, or I do something wrong... EDIT: probably it's related to me using luatex, and luatex automatically puts a .tex behind an extension-less filename, like described here: tex.stackexchange.com/a/128326/44467– crateaneCommented Jun 23, 2015 at 15:53 -
@Faekynn: Please don't edit answers. A comment would have been enough and I would have looked.– user31729Commented Jun 23, 2015 at 19:54
-
The following MWE show how you can directly \input
from, say, the date
command. It also shows how to \read
the output of date
in a control sequence, by means of \openin
.
\documentclass[a4paper]{article}
\usepackage[T1]{fontenc}
\newread\teststream
\newcommand*\testline{}
\openin\teststream=|date
\ifeof\teststream
\typeout{Unable to open test stream.}
\else
\typeout{Test stream opened.}
\read\teststream to \testline
\typeout{\testline}
\fi
\begin{document}
\input{|date}
\end{document}
However, to avoid problems with special characters, it is probably better to use \readline
innstead of \read
, if you are running with e-TeX extensions enabled (as you ordinarily do, nowadays).
Of course, the above code requires that you enable the shell-escape feature.
Addition
I think it may be useful to add references to a couple of related (questions and) answers: first of all (and above all) there is Write18: capturing shell (script) output as command/variable?; however, none of the answers to this question (or to this other, related one) mention the fact that the “piped input” feature also works with \openin
. For this reason, I take the liberty to cite also Include/input every subfile from a subfolder, even if it includes an answer by myself (and this surely qualifies as self-promotion, which isn’t very nice -- please be forgiving).
-
This solution is nice, but unfortunately not suitable for me: I do want to read the output on the console, and with the other solution I simply added an
echo
before eachexit
to my script...– crateaneCommented Jun 22, 2015 at 18:29 -
The advantage of this solution is the testing if the stream exists. Nice solution!– user31729Commented Jun 22, 2015 at 18:31
You can try to use my iexec package, which checks the exit code automatically. If it's not equal to zero, the compilation will stop with an error:
\documentclass{book}
\usepackage{iexec}
\begin{document}
\iexec{./my-script.sh}
\end{document}
The output of ./my-script.sh
will automatically be included into the document. This can be disabled with quiet
option:
\iexec[quiet]{./my-script.sh}
\input{|"someCommand --withOptions and arguments"}
you can\input
from the standard output ofsomeCommand --withOptions and arguments
. This also works with\openin
. See also this answer that is somehow related.