Скрипт Bash запускается вручную, но не работает на crontab
Я новичок в сценариях оболочки. Я написал сценарий оболочки для инкрементного резервного копирования базы данных MySQL. Этот сценарий находится в исполняемом формате и успешно выполняется при выполнении вручную, но завершается неудачно при выполнении через crontab.
Запись в Crontab выглядит так:
*/1 * * * * /home/db-backup/mysqlbackup.sh
Ниже приведен код сценария оболочки -
#!/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 это не показывает никаких ошибок. Как я могу узнать, работает скрипт или нет?
- Во-вторых, как правильно выполнить скрипт оболочки в 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
6 ответов
Возможно, проблема в том, что ваш $PATH отличается в ручной среде от той, в которой работает crontab. Следовательно, which
не могу найти ваши исполняемые файлы. Чтобы это исправить, сначала напечатайте ваш путь в ручной среде (echo $PATH
), а затем вручную установите PATH в верхней части скрипта, который вы запускаете в crontab. Или просто обратитесь к программам по их полному пути.
Редактировать: добавить это в верхней части вашего сценария, прежде чем все 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"
Другой более общий способ - запускать процесс входа пользователя в систему через cron. В дополнение к PATH, он также выберет все параметры LD_LIBRARY_PATH, LANG, другие переменные среды и т. Д. Для этого закодируйте свою запись в crontab следующим образом:
34 12 * * * bash -l /home/db-backup/mysqlbackup.sh
Моя проблема заключалась в том, что я установил задание cron в /etc/cron.d (Centos 7). Кажется, что при этом мне нужно указать пользователя, который выполняет сценарий, в отличие от ввода cronjob на уровне пользователя.
Все, что мне нужно было сделать, это
*/1 * * * * root perl /path/to/my/script.sh
*/5 * * * * root php /path/to/my/script.php
Где "root" означает, что я запускаю скрипт как root. Также необходимо убедиться, что в верхней части файла определено следующее. Ваши пути могут быть разными. Если вы не уверены, попробуйте команду "which perl", "which php".
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
Просто импортируйте свой профиль пользователя в начале скрипта.
то есть:
. /home/user/.profile
сначала запустите команду env > env.tmp, затем запустите cat env.tmp, скопируйте PATH=.................. Полную строку и вставьте в crontab -e, строку перед вашими cronjobs. как показано ниже
++=============================================================++
(# Edit this file to introduce tasks to be run by cron.
#
# Each task to run has to be defined through a single line
# indicating with different fields when the task will be run
# and what command to run for the task
#
# To define the time you can provide concrete values for
# minute (m), hour (h), day of month (dom), month (mon),
# and day of week (dow) or use '*' in these fields (for 'any').
#
# Notice that tasks will be started based on the cron's system
# daemon's notion of time and timezones.
#
# Output of the crontab jobs (including errors) is sent through
# email to the user the crontab file belongs to (unless redirected).
#
# For example, you can run a backup of all your user accounts
# at 5 a.m every week with:
# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
#
# For more information see the manual pages of crontab(5) and cron(8)
PATH=/root/.nvm/versions/node/v18.12.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/sna>
# m h dom mon dow command
0 3 * * * bash /home/ubuntu/test.sh
* * * * * bash /home/ubuntu/test2.sh >> /home/ubuntu/cronlog.log
* 3 * * * bash /home/ubuntu/logscron.sh)
++=====================================================================++
В вашем файле crontab запись сценария может иметь
* * * * * /bin/bash /path/to/your/script
Обязательно используйте в скрипте полные пути. Я просмотрел его и ничего не видел, но на всякий случай пропустил.