开发者

Linux crontab doesnt launch a script

开发者 https://www.devze.com 2023-01-16 03:27 出处:网络
I have this user crontab (accessed via the command crontab -e): # m hdom mon dowcommand */3 * * * *sh /home/FRAPS/Desktop/cronCheck.sh

I have this user crontab (accessed via the command crontab -e):

# m h  dom mon dow   command
*/3 * * * *          sh /home/FRAPS/Desktop/cronCheck.sh

The script cronCheck.sh looks like that:

#!/bin/sh
SERVICE='Script'

if ps ax | grep -v grep | grep -i "$SERVICE" > /dev/null
then
    echo "######开发者_运维技巧## $SERVICE service running, everything is fine ##################\n" >> CronReport.txt
else
    echo "$SERVICE is not running. Launching it now\n" >> CronReport.txt
    perl Script.pl 
fi

When I launch the script (cronCheck.sh) from its own directory, it works like a charm, but when cron launches it, it always "# $SERVICE service running, everything is fine ###" despite 'Script' is not running.

Thanks,


Here's an even better way to write that conditional:

services=$(ps -e -o comm | grep -cFi "$SERVICE")
case "$services" in
    (0) 
        # restart service
    ;;
    (1)
        # everything is fine
    ;;
    (*)
        # more than one copy is running
    ;;
esac

By using ps -e -o comm you avoid having to do the silly grep -v grep thing, because only the actual process name appears in the ps output, not the arguments. And grep -cFi counts up the matches and gives you a number, so you don't have to deal with the exit status of a pipeline.

Also, as other posters have implied, you should lead off this script by setting the PATH variable.

PATH=/bin:/usr/bin:/sbin:/usr/sbin
export PATH

You might or might not want to put /usr/local/bin at the beginning of that list, depending on your system. Don't do it if you don't need anything from there.

Final piece of advice: When writing scripts that will execute without user supervision (such as cron jobs), it's a good idea to put set -e at the beginning. That makes them exit unsuccessfully if any command fails.


You need to put the grep -v grep after the grep -i "$SERVICE". The way you have it now it's guaranteed to be true.


Checking the return status of a pipe like that could be problematic. You should either check the $PIPESTATUS array, or you can pipe the final grep into wc -l to count the number of lines.


cron typically does not set up a lot of the environment like a user account does. You may need to modify your script to get things setup properly.


Cron jobs don't get the same environment settings that you get at a shell prompt - those are generally set up by your shell on login - so you want to use absolute rather than relative paths throughout. (i.e. don't assume the PATH environment variable will exist or be set up the same as it is for you at a shell prompt, and don't assume the script will run with PWD set to your home directory, etc.) So:

  • in your crontab entry replace sh with /bin/sh (or remove it if cronCheck.sh is executable, the shebang line will do).
  • in cronCheck.sh add paths to the log file and the perl script.

cronCheck.sh should end up looking something like:

#!/bin/sh
SERVICE='Script'

if ps ax | grep -v grep | grep -i "$SERVICE" > /dev/null
then
    echo "######## $SERVICE service running, everything is fine ##################\n" >> CronReport.txt
else
    # Specify absolute path to a log file that's writeable for the user the
    # cron runs as (probably you). Example: /tmp/CronReport.txt
    echo "$SERVICE is not running. Launching it now\n" >> /tmp/CronReport.txt

    # Specify absolute path to both perl and the script. Example: /usr/bin/perl
    # and /home/FRAPS/scripts/Script.pl
    /usr/bin/perl /home/FRAPS/scripts/Script.pl 
fi

(Again you can get rid of the /usr/bin/perl bit if Script.pl is executable and has the path to the right perl in the shebang line.)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号