我在部署过程中使用了一个类似这样的 bash 脚本,它会安装不同的 cron 作业来运行
#!/bin/bash
echo 'starting after_install.sh'
## unpack and install code ...
## write out current crontab, first configure cron to run as PST
## we want this to run as myuser, not as sudo
sudo -u myuser bash << eof
echo 'remove the current cron tasks'
crontab -r
echo 'running bundle install'
/home/myuser/.rvm/gems/ruby-2.4.1/wrappers/bundle install
echo 'install cron tasks'
(crontab -l 2>/dev/null; echo "TZ=America/Los_Angeles")| crontab -
(crontab -l 2>/dev/null; echo "CRON_TZ=America/Los_Angeles")| crontab -
(crontab -l 2>/dev/null; echo "00 00 * * * /bin/bash /var/www/application/bin/midnight.sh")| crontab -
(crontab -l 2>/dev/null; echo "00 04 * * * /bin/bash /var/www/application/bin/monday_hr_emails.sh")| crontab -
(crontab -l 2>/dev/null; echo "00 09 * * * /bin/bash /var/www/application/bin/daily-notifications.sh")| crontab -
(crontab -l 2>/dev/null; echo "30 13 * * * /bin/bash /var/www/application/bin/daily-synchronizations.sh")| crontab -
(crontab -l 2>/dev/null; echo "30 * * * * /bin/bash /var/www/application/bin/job-data.sh")| crontab -
(crontab -l 2>/dev/null; echo "00 * * * * /bin/bash /var/www/application/bin/oauth.sh")| crontab -
crontab -l
eof
## do some other stuff ...
然而,这些任务仍然顽固地在 UTC 而不是洛杉矶运行 - 我能做些什么来解决吗?
答案1
CRON 是一个守护进程,它根据系统日期/时间(而不是您决定设置的任何时区)来获取日期/时间信息。因此,如果您的服务器在 UTC 时间运行,则所有 cron 作业都将根据服务器时间启动。我考虑过也许您可以停止或终止 cron,更改 TZ,然后重新启动 cron。但我认为这行不通,因为当它生成(或重新生成)时,如果我没记错的话,实际上是 init.d 启动了它。而且 init.d 仍将使用系统(UTC)时间。
我不确定你用这个脚本想要实现什么,所以也许你可以澄清一下。只是猜测一下……你是想使用用户的本地时间插入作业吗?所以当波士顿的人想在午夜运行作业,而阿纳海姆的人也想在午夜运行作业时,他们不必计算偏移量?
我认为最好的方法是将所有所需时间转换为 UTC 时间(或服务器时间),然后让系统按预期方式处理。如果问题是用户/管理员不确定 UTC 时间,并输入了错误时间启动的作业,认为它是“本地时间”(我遇到过这种情况,做过这样的事情),理论上您可以编写一个脚本,让您在输入 CRON 作业时指定 TZ。例如:
addcron -z "America/NewYork" 00 00 * * * $HOME/midnight_job.sh
addcron 脚本会计算出 UTC 时间中分钟和小时字段的值,通过确定所选的 TZ 是 UTC-5,将 00 00 替换为 00 19,然后再将其实际添加到 cron 表中。请记住,您可能还必须处理工作日!(美国东部时间周日晚上 10:30 相当于 UTC 时间周一凌晨 3:30)