如果我通过 定义我的 cron 调度程序crontab -e
,调度程序将正常工作。但是,在我的情况下,将文件放入/etc/cron.hourly/
不起作用。
运行run-parts --test /etc/cron.hourly
输出脚本。此外,脚本名称是my_sql_backup
且没有文件扩展名。
该脚本具有root:root
777权限。
调度cron.hourly
程序似乎正在工作,因为这是输出grep CRON /var/log/syslog
:
Mar 1 11:17:01 my-instance CRON[12919]: (root) CMD ( cd / && run-parts --report /etc/cron.hourly)
另外,如果我手动运行该命令,调度程序就会按应有的方式运行:
sudo bash -c "cd / && run-parts --report /etc/cron.hourly"
然而,这似乎实际上不起作用。脚本将 MySQL 数据库备份到 Google Cloud Storage,但当我通过 Web 控制台检查时,存储并未更新。
我这里是不是漏掉了什么?为什么我放入的调度程序脚本/etc/cron.hourly/
不起作用?
更新
在我把这echo test > /tmp/foobar.tmp
行添加到我的 cron 脚本后,我发现 tmp 文件就在那里。事实上,我发现了脚本发出的我自己的 tmp 文件。
脚本内容如下。那么问题是否发生在运行gsutil
命令时?
# define environment variables here
sudo sh -c "mysqldump -u$MYSQL_USER -p$MYSQL_PASS $MYSQL_DBNAME --single-transaction | gzip -9 > $MYSQL_TEMPPATH" >/dev/null 2>&1
gsutil cp $MYSQL_TEMPPATH gs://$GS_BUCKET_NAME/$MYSQL_S3_DESTPATH >/dev/null 2>&1
同样,如果我手动运行它,脚本就会正常工作,因此环境变量被设置为正确的值......
更新2
最后我获取到命令发出的日志文件之后发现gsutil
,里面有如下内容:
AccessDeniedException:403 OAuth2 范围不足,无法执行此操作。
我仍然需要调查为什么如果运行时访问会被拒绝/etc/cron.hourly/
...但问题出在gcloud
,而不是 cron...感谢您在评论中的支持。
答案1
在调查了日志输出后,我最终发现日志文件包含以下内容,这些内容来自执行gcloud
:
AccessDeniedException:403 OAuth2 范围不足,无法执行此操作。
因此问题出在 上gcloud
,而不是 cron 上。
那么如何避免 gcloud 上出现访问被拒绝错误?
为了授予虚拟机访问云存储的权限,请执行以下步骤:
停止您的虚拟机实例
编辑您的虚拟机以将云存储从读到读/写。
重启虚拟机
现在我终于让它按计划运行了......
答案2
您没有提供足够的脚本信息来了解它应该做什么,也不知道为什么它可能在 cron 作业中失败 - 有几个常见原因。
但是,您的问题的标题和第一段(关于用户和根 crontab)似乎足够清楚,因此让我们回答:
用户 crontab 和 root crontab 具有格式略有不同,并且不可互换。
例子:
1 1 * * * root /bin/foo // root crontab in /etc/cron*
1 1 * * * /bin/foo // user crontab in /var/spool (see it using the 'crontab' command
发现区别了吗?root crontab 有一个额外的字段来指定用户。用户不必是 root……尽管实际上通常是 root。
假设您要运行数据库备份作业。将根 crontab 添加到 /etc/cron.d/ 以触发您的备份脚本。只需触发即可。一个常见的错误是使 crontab 变得比它需要的更复杂。所有逻辑和错误检查以及权限和日志记录都应该在脚本中,而不是 crontab 中。