Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Script produces different result when executed by Bash than by cron

Please consider following crontab (root):

SHELL=/bin/bash
...
...
0 */3 * * * /var/maintenance/raid.sh

And the bash script /var/maintenance/raid.sh:

#!/bin/bash

echo -n "Checking /dev/md0... "
if ! [ $(mdadm --detail /dev/md0 | grep -c "active sync") -eq 2 ]; then
    mdadm --detail /dev/md0 | mail -s "Raid problem /dev/md0" "[email protected]";
    echo "ERROR"
else 
    echo "ALL OK"
fi;

#-------------------------------------------------------

echo -n "Checking /dev/md1... "
...

And this is what happen when...

...executed from shell prompt (bash):

Mail with mdadm --detail /dev/md0 output is sent to my email (proper behaviour)

...executed by cron:

Blank mail is sent to my email (subject is there, but there is no message)


Why such difference and how to fix it?

like image 509
Peter Avatar asked Sep 20 '13 08:09

Peter


People also ask

What is the difference between executing a bash script vs sourcing it?

Sourcing a script will run the commands in the current shell process. Changes to the environment take effect in the current shell. Executing a script will run the commands in a new shell process.

Does cron use bash or sh?

Cron Uses /bin/sh By Default, Not Bash Bash ( /bin/bash ) is a common shell on most distros, and is an implementation of sh. The /bin/sh file is a symlink to an sh implementation, but it isn't always bash. On Debian based systems like Ubuntu, and on macOS, /bin/sh links to dash by default.

What is the use of * * * * * In cron?

It is a wildcard for every part of the cron schedule expression. So * * * * * means every minute of every hour of every day of every month and every day of the week .

How do I know if a cron job is executed?

To check to see if the cron daemon is running, search the running processes with the ps command. The cron daemon's command will show up in the output as crond. The entry in this output for grep crond can be ignored but the other entry for crond can be seen running as root. This shows that the cron daemon is running.


Video Answer


2 Answers

As indicated in the comments, do use full paths on crontab scripts, because crontab does have different environment variables than the normal user (root in this case).

In your case, instead of mdadm, /sbin/mdadm makes it.

How to get the full path of a command? Using the command command -v:

$ command -v rm
/bin/rm
like image 106
fedorqui 'SO stop harming' Avatar answered Nov 02 '22 23:11

fedorqui 'SO stop harming'


cron tasks run in a shell that is started without your login scripts being run, which set up paths, environment variables etc.

When building cron tasks, prefer things like absolute paths and explicit options etc

like image 32
Bohemian Avatar answered Nov 03 '22 01:11

Bohemian