How to execute shell script from LaTeX?

ShellLatex

Shell Problem Overview


I'm trying to do the following in LaTeX:

\documentclass{article}
\begin{document}
\execute{/usr/local/bin/my-shell-script.sh}
\end{document}

The idea is to execute /usr/local/bin/my-shell-script.sh at the moment of .tex document processing and inject its output into LaTeX stream. Is it possible at all?

PS. It's possible through the package I've made: iexec

Shell Solutions


Solution 1 - Shell

I would do something like the following (partially motivated by what Roman suggested): make your LaTeX file be

\documentclass{article}
\begin{document}
\input{scriptoutput.tex}
\end{document}

and generate the file scriptoutput.tex using

/usr/local/bin/my-shell-script.sh > scriptoutput.tex

You could encode this in a makefile if you want to have it run automatically when necessary. Alternatively, you could use the TeX \write18 command,

\documentclass{article}
\immediate\write18{/usr/local/bin/my-shell-script.sh > scriptoutput.tex}
\begin{document}
\input{scriptoutput.tex}
\end{document}

and I think that would automatically run the shell script each time you compile the document. The \immediate is necessary to ensure that the script is run when LaTeX encounters the command, rather than waiting until a page of output is written. (See this question for more on the shipout routine.)

Solution 2 - Shell

As David pointed out, you can use \write18 to call external programs, then \input the resultant output file. However you will probably want to use \immediate\write18 to make sure the script is executed before calling the \input.

Alternatively, if you use newer versions of pdf(la)tex (after 1.40, I think), you can pipe the output directly into the document, by using a piped input command:

\documentclass{article}
\begin{document}
\input{|"/usr/local/bin/my-shell-script.sh"}
\end{document}

For either method you will need to enable external program calls. For TeXlive distributions, you need to call latex with the -shell-escape option, or for MikTeX, I believe the option is -enable-write18.

Solution 3 - Shell

You can do this in TeX. This paper (PDF) shows you how to write and execute a virus within TeX. The same principles apply for executing a shell script. However in my opinion it is more practicable to write a Makefile, which runs before your LaTeX run and inserts the result.

Solution 4 - Shell

On Ubuntu 11.10 GNU/Linux

pdflatex --enable-pipes --shell-escape mytexfile

with

%...
[This section currently is 
\input{|"wc kmb-box.tex| tr -s ' ' | cut -d' ' -f 4"}
% 2000 characters are allowed here

\input{kmb-box}

%...

works nicely. ie, this uses wordcount (wc) to report how many characters are in the file kmb-box.tex, which is part of (included in) the document.

(btw If you wanted words rather than characters, just change the number in "-f 4")

Solution 5 - Shell

Unless it is imperative that the script is run while LaTeX is running I would recommend just using make to run LaTeX and you script.

I have used that approach to add word counting for articles and including statistics on bibliographic references.

Let your script generate a .tex file and include that in you LaTeX source file.

Below is a snippet from one of my Makefiles:

TEX	= 	/usr/texbin/pdflatex
PREVIEW = /usr/bin/open

REPORT	=	SimMon
REPORT_MASTER = $(REPORT).tex

TEX_OPTIONS = -halt-on-error

SimMon:	 $(REPORT_MASTER) countRefferedPages
	$(TEX) $(TEX_OPTIONS) $(REPORT_MASTER)
	@$(PREVIEW) $(REPORT).pdf

countRefferedPages:	BibTeXPageCount
	cat *.tex | support/BPC/build/Debug/BPC Castle.bib > litteraturTotal.tex

Solution 6 - Shell

This is how I do it with my own iexec package:

\documentclass{article}
\usepackage{iexec}
\begin{document}
\iexec{/usr/local/bin/my-shell-script.sh}
\end{document}

When the output is not required, I can do just this:

\iexec{/usr/local/bin/my-shell-script.sh > /dev/null}

Solution 7 - Shell

I don't think this is possible. I would use a simple preprocessor for that. I.e. change the document to

\documentclass{article}
\begin{document}
%%OUTPUT%%
\end{document}

and preprocess it with

#!/usr/bin/perl -lp
BEGIN { $output = `/usr/local/bin/my-shell-script.sh`; }
s/%%OUTPUT%%/$output/g;

Command:

perl so.pl template.tex > preprocessed.tex

or in-place:

perl -i so.pl template.tex

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionyegor256View Question on Stackoverflow
Solution 1 - ShellDavid ZView Answer on Stackoverflow
Solution 2 - ShellSimon ByrneView Answer on Stackoverflow
Solution 3 - ShellqbiView Answer on Stackoverflow
Solution 4 - ShellCPBLView Answer on Stackoverflow
Solution 5 - ShellNiels CastleView Answer on Stackoverflow
Solution 6 - Shellyegor256View Answer on Stackoverflow
Solution 7 - ShellRoman CheplyakaView Answer on Stackoverflow