From: Eric on
On 2010-07-06, Barry Margolin <barmar(a)alum.mit.edu> wrote:
> In article <slrni3411t.ll4.glennj(a)smeagol.ncf.ca>,
> Glenn Jackman <glennj(a)ncf.ca> wrote:
>
>> At 2010-06-30 12:07AM, "Ant" wrote:
>> > G'day
>> >
>> > The following line from crontab
>> >
>> > 45 13 * * * /usr/bin/cp /export/home/cckell/scratch
>> > /export/home/cckell/scratch.`/usr/bin/date '+\%A'`
>> [...]
>> > The \ is necessary to escape the %, but I did not expect it to appear in
>> > the output.
>>
>> Try double quotes instead of single quotes.
>
> Why do you think that will make a difference? The only difference
> between single and double quotes is when the string contains variable,
> arithmetic, or command substitutions.
>

Well actually, no.

But to start with the crontab line, the % will be replaced by a newline
by cron unless it is escaped either with a backslash or with its own
double quotes "%". So you need the backslash. Unfortunately there is a
bug in many (all?) Solaris versions which means that although it will
obey the backslash it will not remove it as it should before passing
the command to the shell.

So the shell sees the backslash, inside single quotes where it is _not_
special, and leaves it in the argument given to date. If double-quotes
were used instead, cron would not do anything different, so the shell
would see a backslash inside double-quotes, where it escapes only
backslash, back-tick, double-quote, and dollar, so it is _still_ not
special, and is still passed through to date.

If there were no quotes in the crontab line, the shell would see the
backslash, but is is inside the back-ticks, so it is once again not
special!. If it were in the crontab line without even the back-ticks,
the shell would see it unquoted, when it escapes everything, so that
would work. Also if the back-ticks were replaced by $(...) and there
were no other quotes, it would work.

But you don't really want to know all that, the best answer is still to
put the actual command in a small shell-script, and run that from cron.

E.
From: Geoff Clare on
Eric wrote:

>>> > 45 13 * * * /usr/bin/cp /export/home/cckell/scratch
>>> > /export/home/cckell/scratch.`/usr/bin/date '+\%A'`

> So the shell sees the backslash, inside single quotes where it is _not_
> special, and leaves it in the argument given to date. If double-quotes
> were used instead, cron would not do anything different, so the shell
> would see a backslash inside double-quotes, where it escapes only
> backslash, back-tick, double-quote, and dollar, so it is _still_ not
> special, and is still passed through to date.

Yes.

> If there were no quotes in the crontab line, the shell would see the
> backslash, but is is inside the back-ticks, so it is once again not
> special!.

No.

$ printf '%s\n' `printf %s '\%'`
\%
$ printf '%s\n' `printf %s "\%"`
\%
$ printf '%s\n' `printf %s \%`
%

> Also if the back-ticks were replaced by $(...) and there
> were no other quotes, it would work.

Yes.

$ printf '%s\n' $(printf %s \%)
%

--
Geoff Clare <netnews(a)gclare.org.uk>