10

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
    This question has probably been asked before: with \input{|"someCommand --withOptions and arguments"} you can \input from the standard output of someCommand --withOptions and arguments. This also works with \openin. See also this answer that is somehow related. – GuM Jun 22 '15 at 17:46
  • Thanks! I searched a bit, but I didn't find anything relevant - maybe because I searched for write18 and not generally shell commands... – Faekynn Jun 22 '15 at 17:50
11

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 – Faekynn Jun 23 '15 at 15:53
  • @Faekynn: Please don't edit answers. A comment would have been enough and I would have looked. – user31729 Jun 23 '15 at 19:54
  • OK! I'll keep that in mind :) – Faekynn Jun 23 '15 at 21:15
11

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 each exit to my script... – Faekynn Jun 22 '15 at 18:29
  • The advantage of this solution is the testing if the stream exists. Nice solution! – user31729 Jun 22 '15 at 18:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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