# Ignore escape characters when printing string in shell script

I just wrote a simple shell script to save a LaTeX expression as a PNG file. It works fine, except for the LaTeX-syntax for "next row", i.e. the double backslash \\.

When for instance my input expression is like this:

\left( \begin{array}{cc}1 & 2\\ 3 & 4\end{array} \right)


The double backslash is reduced to a single one. I know I can add more backslashes in my expression, but I want those expressions to be genuine LaTeX, not some weird LaTeX-bash combination.

My script:

#!/bin/bash

if [ $# -ne 2 ]; then echo -e "Er moeten twee argumenten worden opgegeven:\n(1) LaTeX code\n(2) Bestandsnaam zonder extensie" else SaveDir="/home/pieter" echo "\documentclass{article}\usepackage[utf8x]{inputenc}\pagestyle{empty}\begin{document}$1$\end{document}" > /tmp/$2.tex
latex -output-directory /tmp -interaction=batchmode $2.tex dvips -o /tmp/$2.ps -E /tmp/$2.dvi convert -units PixelsPerInch -density 200 /tmp/$2.ps -trim $SaveDir/$2.png
fi


So, how can I ignore the escape characters and literally print my LaTeX expression? Preferably without using sed.

• I realised I didn't translate the Dutch phrases. When calling the script you have to give two arguments: the LaTeX expression itself and the filename, without extension. For instance: sh .LaTeX2PNG.sh "B_n(f;x) = \sum_{r=0}^n f \left( \frac{r}{n} \right) {n \choose r} x^r (1-x)^{n-r}" Bernstein Oct 2, 2011 at 7:43

All characters are interpreted literally between single quotes. You used double quotes, and some characters ($"\) are interpreted between double quotes. See What is the significance of single and double quotes in environment variables? The example in your question happens to never use problematic characters, though. Further potential issues that you avert are using echo (the echo built-in performs backslash expansion in some shells, but not in bash unless you explicitly enable it), and a lack of double quotes around $1 (echo $1 would perform backslash expansion; echo "$1" doesn't, in bash).

A safe, portable way to print a string literally is

printf '%s\n' "$1"  Remove \n if you don't want a newline after the string. Is this your real code? If it is, make sure that the problem isn't in the way you're passing the arguments — you should write something like myscript '\left( \begin{array}{cc}1 & 2\\ 3 & 4\end{array} \right)' filename  If you need a single quote inside the TeX snippet, you'll have to escape it: '\''. You may be interested in the here document construct, which would allow you to conveniently have a multiline string in your source file. Or you can include a multiline string in single quotes. printf '%s' '\documentclass{article} \usepackage[utf8x]{inputenc} \pagestyle{empty} \begin{document} $'"1"'$ \end{document} ' >"/tmp/$2.tex"


Note that you should use double quotes around $2 too. Always use double quotes around a variable substitution, unless you have a good reason not to. If the TeX you want to output is fixed in your script, the safest is to use something like this: cat >$2.tex << 'ENDHEADER'
\documentclass{article}
\usepackage[utf8x]{inputenc}
\pagestyle{empty}
\begin{document}
$ENDHEADER echo 1 >> 2.tex cat >> 2.tex << 'ENDFOOTER'$
\end{document}
ENDFOOTER


The data between the cat and END markers will be output as is with no substitutions. (I'm assuming all the newlines added are ok.)

Make sure you use hard quotes (') when you pass your TeX as an argument:

./your_script '\left( \begin{array}{cc}1 & 2\\ 3 & 4\end{array} \right)'
`
• Ah of course, the single (hard) quotes! Thank you. I didn't know about the cat -construction, why is it safer than the echo command? Oct 2, 2011 at 8:08
• Because you can write your TeX without having to worry about the shell munging it.
– Mat
Oct 2, 2011 at 8:10
• Good point, and because of this construction it looks clearer, using the newlines and indentation. Oct 2, 2011 at 8:19