Verbatim Shell-Escape – Provide a Verbatim Commandline for Executing with \write18

shell-escapeverbatim

When using \write18 to execute shell commands, there are some cases where lots of backslash strings, and other 'special' LaTeX characters are required in the commandline to be executed (e.g. if a regular-expression is needed, or when using awk).

It would be convenient to have a way of typing the command exactly as it should appear when used on the commandline (i.e. without needing to use \string, etc.), and having it parsed verbatim, and given as an argument to \write18. What ways are there of accomplishing this?

Best Answer

You can try

\write18{\unexpanded{...}}

In order to avoid doubled # marks and to use %, you can define

\def\exec{\begingroup\setexeccatcodes\innerexec}
\def\setexeccatcodes{\catcode`\#=12 \catcode`\%=12 }
\def\innerexec#1{\immediate\write18{\unexpanded{#1}}\endgroup}

However you can't use \exec in the argument of another command, because this freezes category codes. Should you need it, one has to work also with \scantokens. Braces must be balanced, but this should not be a problem.

Another possibility, suggested by Martin Scharrer, is to use \detokenize:

\def\exec#1{\immediate\write18{\detokenize{#1}}}

which however might insert unwanted spaces in case backslashes are used in the argument. The advantage is that this macro can be used in arguments to other commands.