Double pipe "||" not working in cron jobs

fellow SUers,

I am trying to run a watchdog cron job to make sure a process is running (DreamHost keeps killing processes). I was inspired by this SU question.

However, the double pipe || seems not working.

My cron entry:

# watchdog MAILTO="" @daily . ~/.bashrc && cd /home/chucknorris/workingfolder/ && pgrep -f "python /home/chucknorris/workingfolder/web2py.py -K LLBean" > /dev/null || echo Hello

The problem is: If the python process is not running, I don't get the `Hello' message mailed to me.

If I change to single pipe |

pgrep -f "python /home/chucknorris/workingfolder/web2py.py -K LLBean" > /dev/null | echo Hello

The cron job runs fine. I got the message Hello if my python process is running.

On the other hand, the double pipe runs fine directly in the shell.

So it seems to me || does not work only in the cron job.

Would you please help me figure out why?

Thanks!

1

2 Answers

I think here is not a reason, why it is not functional.

double pipe "||" is logical OR operator in shell expression.

Your command is something like this:

cmd_group_1 && cmd_group_2 && cmd_group_3 || cmd_group_4

For example:
A)

  1. *cmd_group_1* execution fail --> then exit code will not be equal to zero
  2. *cmd_group_4* will BE executed

B)

  1. *cmd_group_1*,*cmd_group_2*,*cmd_group3* execution pass
  2. *cmd_group_4* will NOT BE executed

EDIT:
I test below mentioned crontab entry in cron and it is working:* * * * * aaa || echo "hello" >>/tmp/testaaa is non-existing command so this fail and hello will be written into /tmp/test

2

The @period replaces the date and time specification; IMHO cron should produce an error in syslog telling about "." being an invalid user. Unless this is already a user crontab.

Your question is not giving any detail about the context: - distribution - version - where this cron is stored (path is critical for some aspects) - name of file (name is also critical) - cron conf file

In particular, the extract you provide does not specify the shell used; and you are loading a bashrc file, while bash is almost never the shell used. So, depending on the content of your bashrc file, the behaviour is already unpredictable at the level of trying to execute the dot.

Depending on the shell, && may be unsupported.

About the last part of your line never being interpreted, it's probably because it's just never read by the shell. Fact is, most cron implementations have a max length; and any byte after this limit is just ignored. This limit may vary with implementations between 128 and 1024 bytes, for what I have met. Most frequent values are 192 and 256. And of course, cron does not report this issue in syslogs (not even at reload).

Since you are not giving any context, you have to read the manpage yourself, depending on your distribution, your version, and the cron package used.

I know I am not really answering the question, because the question phrased is ambiguous, and can not receive an answer.

You can test the global syntax with shorter line, like:

* * * * * root /bin/true && echo true || echo false
* * * * * root /bin/false && echo true || echo false

then put your code in a script (I put user scripts in ~/.sh/ , and system ones in /usr/local/bin for user accessible script, and /usr/local/sbin for user unaccessible ones )

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like