6

It seems that using

\immediate\write18{echo "\string#!/bin/bash (version 1)"  > \jobname.command}%

outside of a \newcommand works great. However, I want to invoke within a \newcommand:

\newcommand{\CreateBashScript}{%
   \immediate\write18{echo "\string#!/bin/bash (version 2)"  > \jobname.command}%
}%

but this has an issue with the # (hash / pound symbol).

Notes:

  • To reproduce the problem you need to uncomment the line in the definition of \CreateBashScript.

Code:

\documentclass{article}
\immediate\write18{echo "\string#!/bin/bash (version 1)"  > \jobname.command}%

\newcommand{\CreateBashScript}{%
%    \immediate\write18{echo "\string#!/bin/bash (version 2)"  > \jobname.command}%
}%

\begin{document}
    \CreateBashScript
\end{document}
  • 4
    It's the usual 'you need to double # symbols inside macro definitions' (see e.g. tex.stackexchange.com/questions/42463) – Joseph Wright May 18 '15 at 22:20
  • 1
    @JosephWright: Yep that works great. Thanks. I though that since I was using \string the double ## issue did not occur to me. Also, even though it is the same answer as the linked question, in this case I am not trying to define a macro via a macro which is where the usual doubling of the # comes up. Or at least that was my understanding. – Peter Grill May 18 '15 at 22:25
  • 1
    see this related question somebody once asked tex.stackexchange.com/questions/71632/… :-) – David Carlisle May 18 '15 at 22:26
  • 1
    @PeterGrill the \string isn't executed while the command is being defined, and you need ## to put a # into the replacement text. – David Carlisle May 18 '15 at 22:27
  • 3
    \edef\writehash{\string#} in the preamble and \writehash where you want to print a hash mark. – egreg May 18 '15 at 22:35
6

Since macros are expanded in a \write, I'd have

\edef\shebang{\string#!/bin/bash}

in the preamble so that you can use

\newcommand{\CreateBashScript}{%
    \immediate\write18{echo "\shebang" > \jobname.command}%
}

in the command.

As told in the comment, you could also double the # in the replacement text

\newcommand{\CreateBashScript}{%
    \immediate\write18{echo "\string##!/bin/bash"  > \jobname.command}%
}

but I believe that \shebang is clearer.

2

I fought with this problem for two days now and came across this great answer a thousand times before I understood its relevance. Therefore I attempt to reformulate it, stripped to its essence:

If you want to write out a literal # into some file, you can do something like

\newcommand{\writeouthash}{%
  \immediate\write\myfile{\string##}%
}

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.