我正在尝试设置一个名为 backup_extract.sh 的相对较短的 shell 脚本,该脚本本质上会解压缩 zip 文件,删除数据库,创建同名数据库,然后导入从 zip 文件创建的 sql 文件。
该 zip 文件是在单独的服务器上创建的,然后每天传输到该服务器 - 它是一个 WordPress 网站的简单数据库备份,该脚本旨在在新服务器上恢复该数据库,以作为该服务器的 1:1 克隆用于备份目的的其他网站。
我遇到的问题是,当我只是 bash 运行脚本时,它工作正常,但是当我让 cron 接管时,似乎什么也没有发生。
代码看起来有点像这样(显然省略了mysql用户和密码,以及完整的url,但我向你保证我使用的是文件的确切路径,就好像它们来自根目录一样)
cd /var/www/html/backups/database
mkdir /var/www/html/backups/database/$(date +%Y%m%d)
unzip /var/www/html/backups/database/*.zip -d /var/www/html/backups/database/$(date +%Y%m%d)
mv /var/www/html/backups/database/*.zip /var/ww/html/backups/database/$(date +%Y%m%d)
cd /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer
mv /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer/*.sql /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer/database_$(date +%Y%m%d).sql
mysql -u USERNAME -p'PASSWORD' database -e \ 'DROP DATABASE database';
mysql -u USERNAME -p'PASSWORD' -e \ 'CREATE DATABASE database';
mysql -u USERNAME -p'PASSWORD' database < /var/www/html/backups/database/$(date +%Y%m%d)/dup-installer/database_$(date +%Y%m%d).sql
echo "Backup completed" >> /var/www/html/backups/database/$(date +%Y%m%d)/backup-status.txt
现在这是我第一次写这样的脚本,我确信我做错了一些事情。但让我解释一下这个脚本的作用。
首先,我不知道 cd 命令在涉及 crontab 时是否会执行任何操作,但它们只是以防万一。如果我不需要它们就好了。
第二个目录是使用当前日期创建的
第三,将 zip 文件解压缩到我们刚刚创建的文件夹中 - 这就是事情变得复杂的地方。每天都会有一个新的 zip 文件移动到此文件夹,但是该名称是由不同的服务器按程序生成的,并且无法准确预测 zip 文件的名称,因此我需要一种方法来解压缩存在于其中的任何 zip 文件此文件夹 - 一旦解压缩,它将被移动,因此无需担心一次解压缩多个 zip 文件。
第四,zip 文件被移动到我们在第 2 行创建的文件夹中
第五,我们 cd 进入从 zip 文件解压出来的文件夹
第六,我们将这里的任何sql文件(永远只有1个)重命名为一个更可预测的名称(与zip文件相同的问题,sql文件名是不可预测的,因此很难锁定,所以我使用通配符用于定位该文件夹中的任何 sql 文件。
第七步,我们登录 MySQL 并删除数据库
8、我们登录MySQL并重新创建与我们刚刚删除的数据库同名的数据库
9、我们登录MySQL并导入我们之前重命名的sql文件
第十,我们创建一个任意文本文件,只显示备份已完成
我已经使用 bash -x 多次测试了 shell 脚本,它似乎工作正常。有一些问题,比如它实际上似乎并不关心 .zip 文件位于哪个文件夹中,并且想要解压缩服务器上的每个 zip 文件,这不太好,但核心问题是 crontab 不起作用。我的 crontab 行是这样的:
00 00 * * * /var/www/html/(actual filepath)/backups/backup_extract.sh
我在测试时一直在改变时间,但通常情况就是这样。
当我检查时,/var/log/cron
它的表现就像它已经运行了脚本,但实际上它什么也没做。
我什至尝试创建一个简单的 crontest.sh 文件,该文件仅创建一个 crontest.txt 文件并测试使用 bash 和使用 cron - bash 工作正常,但 cron 不行。
答案1
您是如何创建 crontab 文件的?如果您crontab -e
作为非 root 用户使用,那么该进程将没有足够的权限来修改树/var/www
。
如果您以 root 身份创建它,那么您的 $PATH 可能未设置,因此调用mysql
将失败。
如果您编辑了该/etc/crontab
文件,则会缺少一个username
字段。
第 4 行也有一个拼写错误,其中目标表述为/var/ww/...
答案2
我的解决方案可能对每个人来说都不相同,但基本上crontab -e
根本不起作用。我最终不得不编辑/etc/crontab
。
将 PATH 变量设置为/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin
,将 SHELL 设置为 /bin/bash,然后在该文件中添加我的 cron 作业。现在 cron 作业已正确运行。
我不确定为什么crontab -e
不起作用,我相信更有经验的人可以给出一些可能的原因,但我完全不知道。