Limitation of cron 

http://thread.gmane.org/gmane.linux.debian.user/319121/focus=319134

Subject: What's the problem with this cron command
Newsgroups: gmane.linux.debian.user
Date: 2008-03-15

Hi,

Please take a look at the following cron task:

 * * * * *      root    ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=' > /dev/null || logger get executed.

It bewilders me that it is not doing what I want. Here is the syslog when it is run:

 Mar 15 13:15:02 cxmr /USR/SBIN/CRON[22779]: (root) CMD (ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao
*write|growisofs.*speed=' > /dev/null || logger get executed.)
 Mar 15 13:15:02 cxmr /USR/SBIN/CRON[22780]: (root) CMD ...

I.e., I want to execute a cron task if I'm not burning CD/DVD. But the actual command never get executed, even when I'm not burning CD/DVD. If I redo the command from the command line, it is fine:

$ (ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=' > /dev/null || logger get executed.)
$ tail /var/log/syslog
Mar 15 13:16:27 cxmr tong: get executed.

So, what is the problem?

PS. I'm sure the PATH is setup properly in my cron, so cron can find ps & grep.

xpt

Limitation of cron 

Subject: Re: cron and command quote
Newsgroups: gmane.linux.debian.user
Date: 2008-03-17

On Sun, 16 Mar 2008, NN_il_Confusionario wrote:

> > * * * * *  root    ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao
> > *write|growisofs.*speed=' > /dev/null || logger get executed.
> > PS. I'm sure the PATH is setup properly in my cron, so cron can find ps
> > & grep.
>
> You could, for debugging pourposes:
> * look at mails that cron sends if a commnd give any output;
> * replace temporarilly the command with
>   set -x;echo $PATH;which ps;which grep;which find;which logger;ps -eaf | grep -E ...
> * replace the command with a shell script which executes the command in a shell
>   with set -x and/or other shell debugging options; for example also
>   temporarilly drop redirection to /dev/null

Thanks a lot. With your suggestion, I found the reason — it is as people (e.g. Raj) have suspected, it's problem of cron and quotes.

Here is the execute log:

 Mar 17 17:28:01 cxmr /USR/SBIN/CRON[26757]: (root) CMD (set -x;which ps;which grep;ps -eaf | grep -E
'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=' || logger get executed.)

The mail that I got says:

 + which ps
 /bin/ps
 + which grep
 /bin/grep
 + ps -eaf
 + grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
 root     26757 26756  0 17:28 ?        00:00:00 /bin/sh -c set -x;which ps;which grep;ps -eaf | grep -E 'cdrecord.*
-[dts]ao |cdrdao *write|growisofs.*speed=' || logger get executed.
 root     26761 26757  0 17:28 ?        00:00:00 grep -E cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=

I.e., somehow, the 'ps | grep' was able to find something in cron, whereas when executed directly under shell:

$ ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
$ /bin/sh -c "ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='"

I.e., if the same command are executed directly under shell the 'ps | grep' finds nothing.

Anyone can give some explanation?

xpt

Limitation of cron 

On Tue, 18 Mar 2008, s. keeling wrote:

>>  I.e., somehow, the 'ps | grep' was able to find something in cron, whereas
>>  when executed directly under shell:
>>
>>   $ ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
>>
>>   $ /bin/sh -c "ps -eaf | grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='"
>>
>>  I.e., if the same command are executed directly under shell the
>>  'ps | grep' finds nothing.
>>
>>  Anyone can give some explanation?
>
> Yes.  you're stressing either the tool, or your knowledge of it.  Put
> the relevant bits in a shell script and tell cron to execute that.
> Then you'll have full control.  It won't be hampered by cron's (by
> design) limitations.

Nope, that didn't work. Thanks for the suggestion though s. keeling.

Here is what happened after I followed the above advice.

Now the crontab reads:

 * * * * *      root    is_burning || logger get executed.

The mail that I got says:

+ set -x
+ ps -eaf
+ grep -E 'cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed='
root     15306 15295  0 09:29 ?        00:00:00 grep -E cdrecord.* -[dts]ao |cdrdao *write|growisofs.*speed=
+ exit 0

when executed directly under shell:

$ is_burning || echo not burning CD/DVD
not burning CD/DVD

I.e., having put the 'ps | grep' part into a shell script, the behavior is still the same.

xpt

[Solved] grep and cron & command line 

On Tue, 18 Mar 2008, Bob McGowan <at> symantec.com wrote:

>> Now the crontab reads:
>>
>>  * * * * *    root    is_burning || logger get executed.
>>
>> + set -x
>> + ps -eaf
>> + grep -E  -[dts]ao |cdrdao *write|growisofs.*speed='
>> root     15306 15295  0 09:29 ?        00:00:00 grep -E cdrecord.*
>> -[dts]ao |cdrdao *write|growisofs.*speed=
>> + exit 0
>>
>> $ is_burning || echo not burning CD/DVD
>> not burning CD/DVD
>>
>> I.e., having put the 'ps | grep' part into a shell script, the
>> behavior is still the same.
>> Does it has anything to do with busybox?
>
> If I followed the above discussion correctly, the OP's concern is that
> sometimes the grep will return a result, even when the specified cd
> related programs are not running, and that this happens when the grep is
> run from cron but not from the command line.

Exactly. Right on!

> If this is correct, the results you're seeing can in fact happen in
> either case.  Whether you see a result or not is totally dependent on
> the process scheduler, timing of execution slices and perhaps your
> processor speed and/or if it's an SMP environment.
>
> What's happening is the grep you're running is sometimes finding itself.
>   For example:
>
>    ps -ef|grep firefox|cut -c1-60
>    rmcgowan 17073 16974  0 08:13 ?        00:00:00 /bin/sh /usr
>    rmcgowan 17106 17080  0 08:13 ?        00:00:59 /usr/local/f
>    rmcgowan 30742 17130  0 10:49 pts/1    00:00:00 grep firefox
>
> The last line is the grep that ran.  So, one line is sometimes returned,
> even when firefox is not running.
>
> There are a number of ways to get around the problem.  My favorite is to
> use something that will show up in the ps output for the grep itself but
> which will not be part of what you're looking for.  But this does
> require using either the -l or -f options (which it looks like you are).
>
>    ps -ef | grep '[f]irefox'
>
> will eliminate the grep command itself because the pattern can never
> match itself. . .
>
> I hope this helps solve your problem.

Bingo!!!

That's exactly the reason. As you can see from my script that I've already applied the '[]' trick, but the trick wasn't applied to all 3 grep cases. Having added '[]' to each of the grep cases, I finally see:

Mar 18 21:29:01 cxmr logger: get executed.

Bravo!!!

Thanks a lot to everyone who replied!

xpt