\write18 pass % through to shell

Use \@percentchar instead of %. You need to say \makeatletter before the \write and \makeatother after it to allow for the @ in the macro name if the code isn't located in a package or class or already inside a \makeatletter ... \makeatother block.

There are also \@backslashchar for \ and also \@charlb and \@charrb for { and }. The are listed as "String constants" in my macros2e document as mentioned in Documentation reference for LaTeX internal commands?

You can also now easily define new string macros for any set of characters with the new version of the newverbs package. E.g. to define a macro for the ampersand use:

\usepackage{newverbs}[2011/07/24]
\Verbdef\amp{&}

Note that spaces behind macros are removed also in a \write statement, so you might need to manually insert one using \space.


Here's my two cents about writing percent characters to file:

enter image description here

\documentclass{article}
\usepackage{verbatim}
%
\newwrite\tmpfile
%
\begingroup\lccode`\S=`\%\relax\lowercase{\endgroup\def\mypercent{S}}%
\newcommand\mysecondoftwo[2]{#2}%
%
\immediate\openout\tmpfile test.txt
\immediate\write\tmpfile{Approach 1: Some text and a percent sign\mypercent}%
\immediate\write\tmpfile{Approach 2: Some text and a percent sign\expandafter\mysecondoftwo\string\%}%
\immediate\write\tmpfile{Approach 3: Some text and a percent sign\csname @percentchar\endcsname}%    
\immediate\write\tmpfile{Approach 4: Some text and a percent sign\csname @secondoftwo\expandafter\endcsname\string\%}%        
\makeatletter
\immediate\write\tmpfile{Approach 5: Some text and a percent sign\@percentchar}%
\immediate\write\tmpfile{Approach 6: Some text and a percent sign\expandafter\@secondoftwo\string\%}%
\makeatother
\begingroup
\def\textmacro{Approach 7: Some text and a percent sign}%
\lccode`\S=`\%%
\lowercase{\immediate\write\tmpfile{\textmacro S}}%
\endgroup
\immediate\closeout\tmpfile

\begin{document}
\verbatiminput{test.txt}
\end{document}