我有一个用于压缩数据库和站点文件的脚本,然后将输出转储到服务器上的备份文件夹中。该脚本从命令行运行良好,但它无法通过 cron 工作。
经过大量研究,我认为 cron 无法以当前形式运行它,因为它在不同的环境中运行。
这是脚本,另存为file_name.sh
#!/bin/bash
NOW=$(date +"%Y-%m-%d-%H%M")
FILE="website.com.$NOW.tar"
BACKUP_DIR="/backupfolder"
WWW_DIR="/var/www/website/"
DB_USER="dbuser"
DB_PASS="dbpw"
DB_NAME="dbname"
DB_FILE="website.com.$NOW.sql"
WWW_TRANSFORM='s,^var/www/website,www,'
DB_TRANSFORM='s,^backupfolder,database,'
tar -cvf $BACKUP_DIR/$FILE --transform $WWW_TRANSFORM $WWW_DIR
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME > $BACKUP_DIR/$DB_FILE
tar --append --file=$BACKUP_DIR/$FILE --transform $DB_TRANSFORM $BACKUP_DIR/$DB_FILE
rm $BACKUP_DIR/$DB_FILE
gzip -9 $BACKUP_DIR/$FILE
我目前将脚本存储在/usr/local/scripts/
上面的代码有问题,不允许它通过 cron 运行吗?
它应该进入哪个 crontab? 从终端
crontab -e
,还是/etc/crontab
?它们是两个不同的文件。
我想到了几件事:首先,cron jobs最常见的问题之一是crond通常使用非常小的PATH(通常只是/usr/bin:/bin)运行东西,所以如果脚本使用其他二进制文件目录中的任何命令,它将失败。系统上的mysqldump
在哪里(如果您不确定,请which mysqldump
运行)?如果这是问题所在,在脚本开头添加PATH=/usr/local/bin:/usr/bin:/bin
(或任何适合您情况的内容)应该可以解决它。或者,您可以在 crontab 文件中设置 PATH(将此行放在运行脚本的条目之前)。
如果这不是问题,我的下一步是捕获脚本的输出,如下所示:
1 1 * * * /usr/local/scripts/file_name.sh >/tmp/file_name.log 2>&1
。并查看输出是否具有信息性。顺便说一句,正如@tripleee提到的,cron 条目的格式适用于crontab -e
编辑的文件,但不适用于/etc/crontab。/etc 版本有一个附加字段,指定运行作业的用户,例如
1 1 * * * eric /usr/local/scripts/file_name.sh >/tmp/file_name.log 2>&1
最佳做法是始终使用 crontab -e(生成的文件通常在/var/spool/cron/中),这适用于我曾经使用过的每个 unix 和 linux 平台。
cron 执行的其他常见问题是缺少环境变量。 在 .bash_profile(如果使用 korn shell,则为 .profile)中设置的任何环境变量不一定存在于 cron 环境中。 这可以通过在脚本中包含它们来克服。
正如戈登所说,路径是另一个嫌疑人。 您始终可以在脚本中完整路径可执行文件(例如/bin/mysqldump)。 无论如何,我们中的一些更愤世嫉俗的人都会这样做,以确保我们正在执行我们想要的附加到当前路径中其他同名文件的内容。
我只能猜测您的具体问题,因为您通过创建/script 修复了它,也许/usr/local/scripts 目录上的权限不允许 cron 用户执行?
我不得不删除扩展(.sh),以便在某些情况下运行cron。
修复了它。不确定问题是什么,但这对我有用。
我最初将脚本放在/usr/local/scripts/
我在这里创建了一个新目录 - /scripts/
并将脚本移动到那里。新的crontab -e
命令如下所示:
1 1 * * * bash /scripts/file_name.sh
完美工作。同样,我不确定以前的问题是什么,但现在它可以工作了。