Linux crontab не запускает скрипт - PullRequest
0 голосов
/ 10 сентября 2010

У меня есть этот пользователь crontab (доступ с помощью команды crontab -e):

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

Сценарий cronCheck.sh выглядит так:

#!/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

Когда я запускаю скрипт(cronCheck.sh) из своего собственного каталога, он работает как шарм, но когда cron запускает его, он всегда "# $ SERVICE service работает, все нормально ###", несмотря на то, что Script не работает.

Спасибо

Ответы [ 5 ]

2 голосов
/ 10 сентября 2010

Вот еще лучший способ написать это условие:

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

Используя ps -e -o comm, вы избегаете глупых действий grep -v grep, потому что в выводе ps отображается только фактическое имя процессане аргументы.И grep -cFi подсчитывает совпадения и дает вам номер, так что вам не нужно иметь дело со статусом выхода из конвейера.

Кроме того, как подразумевали другие авторы, вы должны вести этот сценарийустановив переменную PATH.

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

Возможно, вы захотите или не захотите поставить /usr/local/bin в начале этого списка, в зависимости от вашей системы.Не делайте этого, если вам ничего не нужно оттуда.

Последний совет: при написании сценариев, которые будут выполняться без надзора пользователя (например, заданий cron), будет хорошей идеей поставить set -e в начале.Это приводит к тому, что они завершаются неудачно, если какая-либо команда не работает.

2 голосов
/ 10 сентября 2010

Вам нужно поставить grep -v grep после на grep -i "$SERVICE".То, что у вас есть, теперь гарантировано , чтобы быть правдой.

1 голос
/ 10 сентября 2010

Задания Cron не получают те же параметры среды, которые вы получаете в приглашении оболочки - они обычно настраиваются вашей оболочкой при входе в систему - поэтому вы хотите использовать абсолютные, а не относительные пути повсюду.(т.е. не предполагайте, что переменная окружения PATH будет существовать или будет настроена так же, как для вас в приглашении оболочки, и не предполагайте, что скрипт будет работать с PWD, установленным в вашем домашнем каталоге, и т. д.) Итак:

  • в вашей записи в crontab замените sh на /bin/sh (или удалите его, если cronCheck.sh исполняемый файл, подойдет строка shebang).
  • в cronCheck.sh добавьте пути к файлу журнала и сценарию perl.

cronCheck.sh должен выглядеть примерно так:

#!/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

(Опять же, вы можете избавиться от бита / usr / bin / perl, если Script.pl является исполняемым и имеет путь к правому perl в строке shebang.)

1 голос
/ 10 сентября 2010

cron обычно не настраивает большую часть среды, как учетная запись пользователя.Возможно, вам придется изменить ваш скрипт, чтобы все было правильно настроено.

1 голос
/ 10 сентября 2010

Проверка состояния возврата такой трубы может быть проблематичной.Вам следует либо проверить массив $ PIPESTATUS, либо вы можете передать последний grep в wc -l для подсчета количества строк.

...