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
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
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
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