当前位置: 首页>>技术问答>>正文


你如何设置crontab的时区?

, ,

问题描述

我已经设置了ACPI唤醒功能,因此我的笔记本电脑每天早上都会在某个时间唤醒。这个时区是UTC。我想使用UTC设置我的crontabs,以便它们适合唤醒警报。

你怎么做呢?

我已经尝试过编辑/etc/default/cron以包含:

TZ="UTC"

但它不起作用。 (我也试过TZ=UTCTZ="UTC/GMT")

有任何想法吗?

最佳解决办法

我在Trusty(14.04)遇到了类似的问题。通过设置机器的时区解决它,然后重新启动cron服务

  1. sudo dpkg-reconfigure tzdata – 按照说明选择地区/国家

  2. sudo service cron restart

次佳解决办法

没有简单的方法来实现这一目标。 cron使用当地时间。 crontab中的/etc/default/cron和其他TZ规范只是指定TZ应该用于cron启动的进程,它不会影响启动时间。

我见过的大多数解决方案都涉及中间的实用程序,因此cron会启动一些可以确定何时以UTC为单位的内容(例如,如果您知道您只关心DST更改,请在2小时前将其启动,计算时间差,然后开始吧。看看at。为此,人们经常使用perlpython或类似的脚本语言)。

如果你想要的话,有一种讨厌的方式来破解它。 cron只在启动时读取系统中的TZ信息。因此,如果这是一个正在运行的服务器,您可以将TZ设置为UTC,重新启动,并在启动后将其设置为您当地的时区。你也可以编写这个脚本。

作为替代方法,还要看一下cron的@reboot语法,它应该在启动后执行脚本,听起来就像你想要的那样。

第三种解决办法

有一个文件控制系统时区..我只是遇到了同样的问题,这是解决方案:

如果您尚未手动配置任何时区,则运行date应显示UTC时间。

  • 创建备份

    sudo cp /etc/localtime /etc/localtime.bkp
    
  • 删除文件:

    sudo rm /etc/localtime
    
  • 我住在芝加哥,(你可能需要改变路径,使用tab键帮助)所以:

    sudo ln -s /usr/share/zoneinfo/America/Chicago /etc/localtime
    
  • 然后重启。当您的系统启动时执行:date

  • 现在你的时区应该在那里,cron会看看这个。

仅供参考:设置TZ变量是一种临时解决方案,有时可能会充当”mask”。

第四种办法

截至2017年3月,我发现crond支持每个crontab中的CRON_TZ变量。

The CRON_TZ variable specifies the time zone specific for the cron table. The user should enter a time according to the specified time zone into the table. The time used for writing into a log file is taken from the local time zone, where the daemon is running.

– 引自crontab(5)手册页

这允许我指定在本地时间执行每个cronjob的时间,该时间自动计入DST,而服务器保持UTC。

第五种办法

好的,我花了一些时间想出如何在Ubuntu Natty上做这个,这就是我如何使它工作。可能有更优雅的方式,但这种方式有效。

首先,我们需要将cron可执行文件包装在设置TZ变量的shell中。这是如何做:

cd /usr/sbin
mv cron cron.real

然后,创建一个新的/usr /sbin /cron文件。我使用了vim,但你可以使用你想要的任何编辑器,只需使文件看起来像这样:

#!/bin/bash
export TZ=UTC
/usr/sbin/cron.real

使新的cron文件可执行:

chmod ugo+rx cron

现在,重新启动cron守护程序:

service cron restart

您的cron作业现在将在UTC-based计划上运行 – 但是,即使它们执行的时间是UTC,当它们运行时,它们将时区设置为为系统定义的任何时区。要更改它,请在任何命令之前将其放在crontab中:

TZ=UTC

所以你的crontab看起来像这样:

# 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)
# 
# m h  dom mon dow   command
TZ=UTC
00 19 * * * date > /tmp/date.log

第六种办法

  1. 参见/etc/default/cron。你可以在这里为-all-crontabs设置TZ,它应该是TZ=UTC iirc。所以你的方法应该有效。

  2. 看看fcron。您可以在不同的time-zones中设置单独的crontabs:timezone-name 'time zone of the system'在给定时区中运行作业。 timezone-name是一个对环境变量TZ有效的字符串:有关详细信息,请参阅系统文档。例如,”Europe/Paris”在Linux系统上有效。此选项可正确处理夏令时更改。当运行定义此选项的作业时,TZ环境变量设置为时区的值。请注意,如果您提供错误的timezone-name参数,它将被静音忽略,并且作业将在系统的时区中运行。

第七种办法

请参阅我的下一篇文章了解Ubuntu-specific解决方案

我知道这是一个Ubuntu论坛,但我相信答案与你在Red Hat系统上的表现非常相似。我没有方便的Ubuntu系统测试,但我确实在Red Hat上进行了测试。

您需要做的就是在您的cron守护程序init脚本中添加一行。设置并导出环境变量TZ,如下所示:

export TZ=UTC

然后重新启动你的cron守护进程。确保在任何其他变量设置和采购之后将此导出放在cron守护程序启动脚本中 – 我认为这可能是原始海报编辑/etc/default/cron脚本对他不起作用的原因。也许他设置了它,但它然后被脚本中的其他东西重置了。

请注意,这只会影响cron守护程序本身,而不会影响您通过cron运行的作业,因此如果您希望cron作业使用UTC作为其时区,则还必须在作业本身中设置它。

您可能无法逐字复制并让它在Ubuntu框中工作,但这是我用来在Red Hat上测试它的init脚本。您可以在start()功能之前找到导出:

#!/bin/sh
#
# crond          Start/Stop the cron clock daemon.
#
# chkconfig: 2345 90 60
# description: cron is a standard UNIX program that runs user-specified \
#              programs at periodic scheduled times. vixie cron adds a \
#              number of features to the basic UNIX cron, including better \
#              security and more powerful configuration options.

### BEGIN INIT INFO
# Provides: crond crontab
# Required-Start: $local_fs $syslog
# Required-Stop: $local_fs $syslog
# Default-Start:  2345
# Default-Stop: 90
# Short-Description: run cron daemon
# Description: cron is a standard UNIX program that runs user-specified 
#              programs at periodic scheduled times. vixie cron adds a 
#              number of features to the basic UNIX cron, including better 
#              security and more powerful configuration options.
### END INIT INFO

[ -f /etc/sysconfig/crond ] || { 
    [ "$1" = "status" ] && exit 4 || exit 6 
}

RETVAL=0
prog="crond"
exec=/usr/sbin/crond
lockfile=/var/lock/subsys/crond
config=/etc/sysconfig/crond

# Source function library.
. /etc/rc.d/init.d/functions

[ -e /etc/sysconfig/$prog ] && . /etc/sysconfig/$prog

export TZ=UTC
start() {
    if [ $UID -ne 0 ] ; then
        echo "User has insufficient privilege."
        exit 4
    fi
    [ -x $exec ] || exit 5
    [ -f $config ] || exit 6
    echo -n $"Starting $prog: "
    daemon $prog $CRONDARGS
    retval=$?
    echo
    [ $retval -eq 0 ] && touch $lockfile
}

stop() {
    if [ $UID -ne 0 ] ; then
        echo "User has insufficient privilege."
        exit 4
    fi
    echo -n $"Stopping $prog: "
    if [ -n "`pidfileofproc $exec`" ]; then
        killproc $exec
        RETVAL=3
    else
        failure $"Stopping $prog"
    fi
    retval=$?
    echo
    [ $retval -eq 0 ] && rm -f $lockfile
}

restart() {
    stop
    start
}

reload() {
    echo -n $"Reloading $prog: "
    if [ -n "`pidfileofproc $exec`" ]; then
        killproc $exec -HUP
    else
        failure $"Reloading $prog"
    fi
    retval=$?
    echo
}

force_reload() {
    # new configuration takes effect after restart
    restart
}

rh_status() {
    # run checks to determine if the service is running or use generic status
    status -p /var/run/crond.pid $prog
}

rh_status_q() {
    rh_status >/dev/null 2>&1
}


case "$1" in
    start)
        rh_status_q && exit 0
        $1
        ;;
    stop)
        rh_status_q || exit 0
        $1
        ;;
    restart)
        $1
        ;;
    reload)
        rh_status_q || exit 7
        $1
        ;;
    force-reload)
        force_reload
        ;;
    status)
        rh_status
        ;;
    condrestart|try-restart)
        rh_status_q || exit 0
        restart
        ;;
    *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload}"
        exit 2
esac
exit $?

参考资料

本文由Ubuntu问答整理, 博文地址: https://ubuntuqa.com/article/1640.html,未经允许,请勿转载。