Bash script выполняется вручную, но не работает на crontab

Я новичок в сценариях оболочки. Я написал оболочку script, чтобы выполнить инкрементное резервное копирование базы данных MySQL. script находится в исполняемом формате и успешно выполняется при выполнении вручную, но сбой при выполнении через crontab.

Элемент Crontab выглядит следующим образом:

*/1 * * * * /home/db-backup/mysqlbackup.sh

Ниже приведен код оболочки script -

#!/bin/sh
MyUSER="root"       # USERNAME
MyPASS="password"         # PASSWORD
MyHOST="localhost"  # Hostname
Password="" #Linux Password

MYSQL="$(which mysql)"
if [ -z "$MYSQL" ]; then
echo "Error: MYSQL not found"
exit 1
fi
MYSQLADMIN="$(which mysqladmin)"
if [ -z "$MYSQLADMIN" ]; then
    echo "Error: MYSQLADMIN not found"
    exit 1
fi
CHOWN="$(which chown)"
if [ -z "$CHOWN" ]; then
    echo "Error: CHOWN not found"
    exit 1
fi
CHMOD="$(which chmod)"
if [ -z "$CHMOD" ]; then
    echo "Error: CHMOD not found"
    exit 1
fi

GZIP="$(which gzip)"
if [ -z "$GZIP" ]; then
    echo "Error: GZIP not found"
    exit 1
fi
CP="$(which cp)"
if [ -z "$CP" ]; then
    echo "Error: CP not found"
    exit 1
fi
MV="$(which mv)"
if [ -z "$MV" ]; then
    echo "Error: MV not found"
    exit 1
fi
RM="$(which rm)"
if [ -z "$RM" ]; then
    echo "Error: RM not found"
    exit 1
fi
RSYNC="$(which rsync)"
if [ -z "$RSYNC" ]; then
    echo "Error: RSYNC not found"
    exit 1
fi

MYSQLBINLOG="$(which mysqlbinlog)"
if [ -z "$MYSQLBINLOG" ]; then
    echo "Error: MYSQLBINLOG not found"
    exit 1
fi
# Get data in dd-mm-yyyy format
NOW="$(date +"%d-%m-%Y-%T")"

DEST="/home/db-backup"
mkdir $DEST/Increment_backup.$NOW
LATEST=$DEST/Increment_backup.$NOW
$MYSQLADMIN -u$MyUSER -p$MyPASS flush-logs
newestlog=`ls -d /usr/local/mysql/data/mysql-bin.?????? | sed 's/^.*\.//' | sort -g | tail -n 1`
echo $newestlog
for file in `ls /usr/local/mysql/data/mysql-bin.??????`
do
        if [ "/usr/local/mysql/data/mysql-bin.$newestlog" != "$file" ]; then
     echo $file             
     $CP "$file" $LATEST         
        fi
done
for file1 in `ls $LATEST/mysql-bin.??????`
do
 $MYSQLBINLOG $file1>$file1.$NOW.sql 
 $GZIP -9 "$file1.$NOW.sql"     
 $RM "$file1"
done
$RSYNC -avz $LATEST /home/rsync-back
  • Прежде всего, когда запланировано на crontab, он не показывает никаких ошибок. Как я могу узнать, работает ли script?
  • Во-вторых, каков правильный способ выполнения оболочки script в crontab. Некоторые блоги предлагают изменить переменные среды. Что было бы лучшим решением.

Когда я сделал $echo PATH, я получил это

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/mysql/bin:/opt/android-sdk-linux/tools:/opt/android-sdk-linux/platform-tools:~/usr/lib/jvm/jdk-6/bin

Ответ 1

Вероятно, проблема в том, что ваш $PATH в ручной среде отличается от того, в котором работает crontab. Следовательно, which не может найти ваши исполняемые файлы. Чтобы исправить это, сначала напечатайте свой путь в ручной среде (echo $PATH), а затем вручную настройте PATH в верхней части script, которую вы запускаете в crontab. Или просто обратитесь к программам по их полному пути.

Изменить: добавьте это в начало вашего script, перед всеми вызовами which:

export PATH="/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/mysql/bin:/opt/android-sdk-linux/tools:/opt/android-sdk-linux/platform-tools:~/usr/lib/jvm/jdk-6/bin"

Ответ 2

Еще один общий способ - запустить cron для входа в систему bash. В дополнение к PATH, это также будет отображать любые LD_LIBRARY_PATH, настройки LANG, другие переменные среды и т.д. Чтобы сделать это, введите код crontab, например:

34  12  * * *   bash -l /home/db-backup/mysqlbackup.sh

Ответ 3

Мой вопрос состоял в том, что я установил задание cron в /etc/cron.d(Centos 7). Похоже, что при этом мне нужно указать пользователя, который выполняет script, в отличие от того, когда cronjob вводится на уровне пользователя.

Мне оставалось только

*/1 * * * * root perl /path/to/my/script.sh
*/5 * * * * root php /path/to/my/script.php

Где "root" заявляет, что я запускаю script как root. Также необходимо убедиться, что в верхней части файла указано следующее. Ваши пути могут быть разными. Если вы не уверены, попробуйте команду "какой perl", "какой php".

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin

Ответ 4

Просто импортируйте свой профиль пользователя в начало script.

то есть:.

./home/user/.profile