[geeks] Shell quoting question...

Robert Slover robert.j.slover at verizon.net
Fri Jul 14 20:21:26 CDT 2006


> From: velociraptor <velociraptor at gmail.com>
> Date: July 14, 2006 12:47:03 PM EDT
> To: geeks at sunhelp.org
> Subject: [geeks] Shell quoting question...
> Reply-To: The Geeks List <geeks at sunhelp.org>
>
>
> I'm having some trouble with a cron job, I can't figure out how to
> escape it to make it work...
>
> The script takes an argument that is the name of a profile for use by
> another application.  The sole purpose of my script is to wrap the app
> and generate error mail if the run fails.
>
> If the profile exists, the directory exists as well, so I am using
> that as a way to ensure there's no errors in the profile name.
> Unfortunately the profiles are generated by a web interface, so a
> space in the profile name is converted to %20 in the directory name.
> The CLI version of the application that processes the profile will
> accept either the space or %20 when you execute the app in an
> interactive terminal.
>
> In my crontab entry:
>
> 00 05 * * * /export/home/nmiller/script "profile%20name" > /dev/null 
> 2>&1
>
> If I issue the above in an interactive shell, it works fine.
>
> But in the cron log I see this:
>
> sh /export/home/nmiller/script "profile
>
> I tried escaping the %, e.g. "profile\%20name", but that just resulted
> in a line in my cron log with my script's exit code for "bad
> argument".
>
> I suppose I could work around this by doing a transformation in the
> script to check the directory name, but today's my last day, and I
> still have a handful of other things to beat into submission before
> 5:30pm.
>
> Cluebats appreciated...
>
> =Nadine=

Hi Nadine,

This is (unfortunately) right up my alley.

The problem isn't that '%' is special to the shell -- it is special to 
*cron*.  For cron, it means to terminate the job specification at that 
point, and pass what follows as STDIN.  Each subsequent % means 
newline.

I have found the rules for quoting inside of crontab to differ between 
OS's, and I didn't see that specified.  Some cron's treat backslash as 
'special' anywhere outside of double quotes and some treat it as 
special only before '%'.  I have found the following quoting rules to 
be "best" across the OS's I have to work with:

1) The special characters are single quote, backslash, and percent.
2) Each argument is passed inside of single quotes.
3) If any of the special characters needs to occur inside the argument, 
you terminate the single quoted string with a closing single quote, 
then, without a space, start a double-quoted string.  Precede the 
special character inside this double-quoted string with a backslash.  
Terminate the double-quoted string following the special character, 
then resume the remainder of the argument inside single quotes.

For your example:

00 05 * * * /export/home/nmiller/script 'profile'"\%"'20name' > 
/dev/null 2>&1

So, to summarize the rules, single quote all arguments, then you apply 
the following
substitutions to everything inside of single quotes:

'  -->  '"\'"'
\    -->   '"\\"'
%  -->  '"\%"'

HTH

--Robert



More information about the geeks mailing list