12

I have a test.sh script

#!/bin/sh
php /home/v/file.php
sh /root/x/some.sh

when I execute the file as root from command line it works.

sh /home/v/test.sh 

when I set it to crontab -e (is the root cron), is not working

 * * * * * sh /home/v/test.sh

What do I do wrong? Thanks

3
  • "is not working" is not working. See? You don't know what I mean, and likewiese do we not know what you mean. I mean (yes) what is not working? Could be about anything. Could be tmow's guess is correct, but it's only a guess (and pretty good one I think, but still). Commented Feb 2, 2011 at 16:44
  • Yes, if you can be more specific with what results you are seeing, we will be better able to determine what the problem is. I.e., what do you mean "not working" (:
    – gabe.
    Commented Feb 2, 2011 at 16:57
  • I dont see any log in the syslog, and the scripts are doing some inserts into a db which are not happening, and they happend if I run the script by hand. Commented Feb 2, 2011 at 19:11

3 Answers 3

17

According to the man:

The cron daemon starts a subshell from your HOME directory. If you schedule a command to run when you are not logged in and you want commands in your .profile file to run, the command must explicitly read your .profile file.

The cron daemon supplies a default environment for every shell, defining HOME, LOGNAME, SHELL (=/usr/bin/sh),
and PATH (=/usr/bin).

So cron daemon doesn't know where php is and you should specify the full php path by hand, for example (I don't know your real PHP path):

#!/bin/sh
/usr/local/bin/php /home/v/file.php
sh /root/x/some.sh

Another way is to source the /etc/profile (or your .profile/.bashrc), for example

* * * * * . /home/v/.bashrc ; sh /home/v/test.sh

This is useful if your .bashrc set the environment variables that you need (i.e. PATH)

EDIT

An interesting reading is "Newbie: Intro to cron", don't undervalue the article from the title (It's a reading for everybody), in fact it's well written complete and answer perfectly to your question:

...
PATH contains the directories which will be in the search path for cron e.g if you've got a program 'foo' in the directory /usr/cog/bin, it might be worth adding /usr/cog/bin to the path, as it will stop you having to use the full path to 'foo' every time you want to call it.
...

3
  • Bad $PATH is the most common cause of scripts that work by hand, but not from cron.
    – phemmer
    Commented Feb 2, 2011 at 19:10
  • @Patrick Of course it is a problem if cron doesn't know where is php, otherwise the Elzo crontab would work without any issues, it MUST be a PATH problem.
    – tmow
    Commented Feb 3, 2011 at 8:01
  • Thanks a lot for your answer. It worked for me with very easily!!!.. Thanks a lot @tmow. Commented Jan 10, 2016 at 18:07
5

There are four common causes for commands working when typed in a terminal but not from cron, in order of commonness:

  1. Cron provides a limited environment, e.g., a minimal $PATH, and other expected variables missing.
  2. Cron invokes /bin/sh by default, whereas you may be using some other shell interactively.
  3. Cron treats the % character specially (it is turned into a newline in the command).
  4. Cron doesn't provide a terminal or graphical environment.

If your job produces any output, including error messages, cron sends you an email with the whole output. Make sure you read the mail you receive locally or forward it to an address you read. To forward mail from a local account to some other address, put the other address in ~/.forward. If the cron job is running as a system user (root, webmaster, …), make sure that user's mail is redirected to you (and any other admin); with most mail setups, put lines like root: elzo in /etc/aliases.

2

The cron daemon usually executes your command in a shell where the PATH environment variable is restricted to some system default, e.g. /usr/bin:/bin.

Probably, your php command is not available in /usr/bin or /bin and thus the script fails when executed via cron and runs successful when not.

Cron usually reports errors or job messages via a mail to the root user (i.e. when a command returns an exit status != 0 or produces output to stdout/stderr) after the job is finished.

Depending on your system you have to setup local mail delivery to get these messages.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .