3

I'm doing this:

\documentclass{article}
\begin{document}
\write18{echo '100%' > hash.tex}
\input{hash.tex}
\end{document}

However, this doesn't work (doesn't compile). What is the workaround?

yegor256
  • 12,021

2 Answers2

3

Since % is the comment character, you cannot use it that way. There are various solutions available.

The simplest one is to use \@percentchar, but this requires \makeatletter. Simpler is to define an alias in the preamble and use it inside \write:

\documentclass{article}

\makeatletter\let\percentchar@percentchar\makeatother

\begin{document}

\immediate\write18{echo '100\percentchar' > hash.tex} \input{hash.tex}

\end{document}

Less obtrusive might be

\documentclass{article}
\usepackage{shellesc}

\makeatletter \newcommand{\exec}[1]{% \begingroup \let%@percentchar \ShellEscape{#1}% \endgroup } \makeatother

\begin{document}

\exec{echo '100%' > hash.tex} \input{hash.tex}

\end{document}

Why shellesc? Because \ShellEscape works with all engines, so you don't need to change code with LuaLaTeX, for instance. It does \immediate\write18 (or the equivalent), which is what you need: without \immediate, the execution would be deferred to the next page shipout and the subsequent \input would fail.

egreg
  • 1,121,712
1

You can define \sstring macro which behaves like \string but the backslash is not printed. (Note, that LuaTeX has special primitive \cssting for such task.

\def\sstring#1{\expandafter\sstringA\string#1\relax}
\def\sstringA#1#2\relax{#2}

\write18{echo '100\sstring%' > hash.tex}

This is universal solution for all TeX-sensitive characters, for example \sstring\{, \sstring\# etc.

wipet
  • 74,238