คุณตั้งค่าเขตเวลาสำหรับ crontab อย่างไร


63

ฉันได้ตั้งค่า ACPI wakeup เพื่อให้แล็ปท็อปของฉันตื่นขึ้นมาในเวลาที่กำหนดทุกเช้า เขตเวลาสำหรับสิ่งนี้คือ UTC ฉันต้องการตั้งค่า crontabs ของฉันโดยใช้ UTC เพื่อให้พอดีกับการปลุก

คุณจะทำอย่างไรมันได้หรือไม่?

ฉันพยายามแก้ไข/etc/default/cronเพื่อรวม:

TZ="UTC"

แต่มันไม่ทำงาน (ฉันเคยลองTZ=UTCแล้วTZ="UTC/GMT")

ความคิดใด ๆ


1
คุณทำการsudo service cron restartแก้ไขหลังจากหรือไม่
Rinzwind

1
ไม่ ... แต่ฉันลองแล้วก็ไม่ได้สร้างความแตกต่าง
alj


คำตอบ:


44

ฉันมีปัญหาที่คล้ายกันใน Trusty (14.04) แก้ไขโดยการตั้งค่าเขตเวลาของเครื่องจากนั้นเริ่มcronบริการใหม่

  1. sudo dpkg-reconfigure tzdata - ทำตามคำแนะนำเพื่อเลือกภูมิภาค / ประเทศ
  2. sudo service cron restart

1
หลังจากตั้งค่าเขตเวลาคุณสามารถพิมพ์dateที่บรรทัดคำสั่งเพื่อยืนยันว่าวันที่ถูกต้องตามที่คุณคาดหวัง
mydoghasworms

ฉันรีสตาร์ท cron แล้ว แต่ยังคงใช้เขตเวลาเก่า (UTC) อยู่หรือไม่
Luke Fisk-Lennon

สิ่งนี้ทำงานได้อย่างราบรื่นสำหรับฉันในวันที่ 18.10 ~ $ date ส่งคืนเวลาที่ถูกต้อง ต้องรักอินเตอร์เฟสสี GUI สไตล์ DOS ที่มีสีสันสดใสเหล่านั้น! ขอบคุณ
itsricky

18

ไม่มีวิธีง่ายๆในการบรรลุเป้าหมายนี้ cron ใช้เวลาท้องถิ่น /etc/default/cronและTZข้อกำหนดอื่น ๆใน crontab เพียงระบุสิ่งที่TZควรใช้สำหรับกระบวนการที่เริ่มโดย cron จะไม่ส่งผลกระทบต่อเวลาเริ่มต้น

วิธีแก้ปัญหาส่วนใหญ่ที่ฉันเคยเห็นเกี่ยวข้องกับยูทิลิตี้ตรงกลางดังนั้น cron จะเริ่มทำบางสิ่งที่จะตัดสินว่าจะเตะใน UTC เมื่อใด (เช่นถ้าคุณรู้ว่าคุณกังวลเกี่ยวกับการเปลี่ยนแปลง DST เท่านั้นเริ่มจาก 2 ชั่วโมงก่อนคำนวณ ความแตกต่างของเวลาและเตะมันออกแล้วดูที่atการทำเช่นนั้นคนมักจะใช้perlหรือpythonภาษาสคริปต์ที่คล้ายกัน)

มีวิธีที่น่ารังเกียจในการแฮกหากคุณต้องการ cron อ่านข้อมูล TZ จากระบบเมื่อเริ่มต้นเท่านั้น ดังนั้นหากนี่เป็นเซิร์ฟเวอร์ที่ใช้งานอยู่คุณสามารถตั้งค่า TZ เป็น UTC รีบูตและหลังจากการบู๊ตตั้งเป็นเขตเวลาท้องถิ่นของคุณ คุณสามารถเขียนสคริปต์นี้ได้เช่นกัน

ในฐานะที่เป็นวิธีการอื่นให้ดูที่@rebootไวยากรณ์ของ cron ซึ่งควรเรียกใช้งานสคริปต์หลังจากการบูทซึ่งดูเหมือนว่าคุณต้องการ


14

มีไฟล์ที่ควบคุมเขตเวลาของระบบ .. ฉันเพิ่งได้รับปัญหาเดียวกันนี่คือวิธีแก้ปัญหา:

หากคุณไม่ได้กำหนดค่าเขตเวลาด้วยตนเองการเรียกใช้dateควรแสดงเวลา UTC

  • สร้างการสำรองข้อมูล

    sudo cp /etc/localtime /etc/localtime.bkp
    
  • ลบไฟล์:

    sudo rm /etc/localtime
    
  • ฉันอาศัยอยู่ในชิคาโก (คุณอาจต้องเปลี่ยนเส้นทางโดยใช้แท็บช่วยด้วย):

    sudo ln -s /usr/share/zoneinfo/America/Chicago /etc/localtime
    
  • จากนั้นรีบูท เมื่อระบบเริ่มทำงานของคุณ: วันที่

  • ตอนนี้เขตเวลาของคุณควรอยู่ที่นั่นแล้วและ cron จะมองดูสิ่งนี้

FYI: การตั้งค่าตัวแปร TZ เป็นวิธีแก้ปัญหาชั่วคราวและอาจทำหน้าที่เป็น "หน้ากาก" บางครั้ง


1
+1 สำหรับโซลูชันที่เข้ากันได้กับ CentOS (และ EC2 Amazon Linux) เริ่มระบบใหม่เต็มรูปแบบอาจจะเป็นความคิดที่ดี แต่สำหรับฉันdateทำงานได้โดยไม่ต้องรีบูตเครื่องและบาร์รีสตาร์ทระบบปฏิบัติการsudo service crond restartก็เพียงพอที่จะแก้ไขปัญหาของฉันขึ้นครั้งงาน cron
davur

+1 ขอบคุณมันใช้งานได้
จิม

13

เมื่อวันที่มีนาคม 2560 ฉันค้นพบว่า crond รองรับตัวแปร CRON_TZ ในแต่ละ crontab

ตัวแปร CRON_TZ ระบุเขตเวลาเฉพาะสำหรับตาราง cron ผู้ใช้ควรป้อนเวลาตามโซนเวลาที่ระบุลงในตาราง เวลาที่ใช้ในการเขียนลงในล็อกไฟล์นั้นนำมาจากโซนเวลาท้องถิ่นโดยที่ daemon กำลังทำงาน

- อ้างจากหน้าคู่มือ crontab (5)

สิ่งนี้ทำให้ฉันสามารถระบุเวลาในการเรียกใช้งาน cronjob แต่ละรายการในเวลาท้องถิ่นซึ่งคิดเป็น DST โดยอัตโนมัติในขณะที่เซิร์ฟเวอร์ยังคงอยู่ใน UTC


ฉันยังพบการเชื่อมโยงนี้เป็นประโยชน์: serverfault.com/questions/848829/... เพื่อค้นหาตัวเลือกเขตเวลาที่ฉันต้องการฉันป้อนls /usr/share/zoneinfo/Americaเพื่อดูตัวเลือก
cheevahagadog

7

ตกลงฉันใช้เวลาสักครู่แล้วหาวิธีทำสิ่งนี้บน Ubuntu Natty และนี่คือวิธีที่ฉันใช้งานได้ อาจมีวิธีที่หรูหรากว่า แต่วิธีนี้ใช้ได้ผล

ก่อนอื่นเราต้องห่อ cron executable ในเชลล์ที่ตั้งค่าตัวแปร TZ นี่คือวิธี:

cd /usr/sbin
mv cron cron.real

จากนั้นสร้างไฟล์ใหม่ / usr / sbin / cron ฉันใช้เป็นกลุ่ม แต่คุณสามารถใช้โปรแกรมแก้ไขใด ๆ ที่คุณต้องการเพียงแค่ทำให้ไฟล์มีลักษณะดังนี้:

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

ทำให้ไฟล์ cron ใหม่ทำงานได้:

chmod ugo+rx cron

ตอนนี้รีสตาร์ท cron daemon:

service cron restart

งาน cron ของคุณจะทำงานตามตารางเวลา UTC - อย่างไรก็ตามแม้ว่าเวลาที่พวกเขาจะถูกดำเนินการจะเป็น 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
การตั้งค่า TZ = UTC ในสองแห่งคืออะไร คุณใส่มันลงในไฟล์ crontab ไม่ได้เหรอ?
Ph Nng Nguyễn

ไม่ใช่การใส่ TZ = UTC ในไฟล์ crontab จะตั้งค่าเฉพาะสำหรับงาน cron ไม่ใช่สำหรับ cron เอง ไม่ส่งผลกระทบต่อระยะเวลาของการปฏิบัติงาน
Mark Reed

5
  1. /etc/default/cronดู คุณสามารถตั้งค่าTZที่นี่สำหรับ - ทั้งหมด -crontabs และควรเป็นTZ=UTCiirc ดังนั้นวิธีการของคุณควรได้ผล

  2. มีลักษณะที่fcron คุณสามารถตั้งค่า crontabs แยกตามโซนเวลาที่แตกต่างกัน:

    timezone-name 'time zone of the system'

    รันงานในเขตเวลาที่กำหนด timezone-name เป็นสตริงที่ใช้ได้สำหรับตัวแปรสภาพแวดล้อม TZ: ดูเอกสารประกอบของระบบของคุณสำหรับรายละเอียดเพิ่มเติม ตัวอย่างเช่น "Europe / Paris" ถูกต้องบนระบบ Linux ตัวเลือกนี้จัดการกับการเปลี่ยนแปลงการปรับเวลาตามฤดูกาลอย่างถูกต้อง ตัวแปร TZ environ, ment ถูกตั้งค่าเป็นเขตเวลาเมื่องานที่กำหนดตัวเลือกนี้ถูกเรียกใช้

    โปรดทราบว่าหากคุณระบุอาร์กิวเมนต์ชื่อเขตเวลาที่ผิดพลาดจะถูกละเว้นอย่างเงียบ ๆ และงานจะทำงานในเขตเวลาของระบบ


ฉันตรวจสอบแล้ว crontab ทำงานได้ก็ต่อเมื่อฉันตั้งเวลาทริกเกอร์เป็นเวลาท้องถิ่น การตั้งเวลาเป็น UTC ไม่ทำงาน
alj

ดี 4 ปีต่อมาและฉันมองที่ไฟล์ที่ / etc / default / cron และตอนนี้เลิกอย่างเป็นทางการแล้ว
the0ther

โหวตหลังจาก 4 ปี? ใช่มันไม่ถูกต้องในตอนนี้ แต่มันไม่ได้กลับมาในวันนี้ จากนั้นไม่มีใครเป็นผู้ใช้อีก 11.04 ฉันหวังว่า
Rinzwind

3
หากคำตอบนี้ไม่ถูกต้องคุณควรลบออก ไม่มีจุดในการเก็บข้อมูลที่ผิดอย่างรู้เท่าทันบน StackExchange มันเคยเป็นในหัวข้อและ / หรือถูกต้องสวยมากที่ไม่เกี่ยวข้องกับทุกคนที่เข้าชมหน้านี้ในการค้นหาข้อมูลที่ถูกต้อง
Quuxplusone

4

โปรดดูโพสต์ถัดไปของฉันสำหรับโซลูชันเฉพาะของ Ubuntu

ฉันรู้ว่านี่เป็นฟอรัม Ubuntu แต่ฉันเชื่อว่าคำตอบจะคล้ายกับวิธีที่คุณทำบนระบบ Red Hat ฉันไม่มีระบบ Ubuntu ที่มีประโยชน์ในการทดสอบสิ่งนี้ แต่ฉันทดสอบบน Red Hat

สิ่งที่คุณต้องทำคือเพิ่มบรรทัดลงในสคริปต์ init cron daemon ของคุณ ตั้งค่าและส่งออกตัวแปรสภาพแวดล้อม TZ เช่นนี้

export TZ=UTC

จากนั้นรีสตาร์ท cron daemon ของคุณ ตรวจสอบให้แน่ใจว่าคุณใส่การส่งออกนี้ในสคริปต์เริ่ม cron daemon หลังจากการตั้งค่าตัวแปรและการจัดหาอื่น ๆ - ฉันคิดว่านี่อาจเป็นสาเหตุที่การแก้ไข/etc/default/cronสคริปต์ต้นฉบับของโปสเตอร์ไม่ทำงานสำหรับเขา บางทีเขาอาจตั้งค่าไว้ แต่มันก็ถูกรีเซ็ตโดยบางสิ่งบางอย่างเพิ่มเติมลงในสคริปต์

โปรดทราบว่าสิ่งนี้จะมีผลกับ cron daemon เท่านั้นไม่ใช่งานที่คุณทำงานผ่าน cron ดังนั้นหากคุณต้องการให้งาน cron ใช้ UTC เป็นเขตเวลาคุณจะต้องตั้งค่าในงานด้วย

คุณอาจไม่สามารถคัดลอกคำต่อคำนี้และทำงานบนกล่อง Ubuntu แต่นี่เป็นสคริปต์เริ่มต้นที่ฉันใช้ในการทดสอบใน Red Hat คุณจะพบการส่งออกก่อน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 $?

0

เพิ่งพบสิ่งนี้บน Ubuntu 14/16 ทำงานอย่างสมบูรณ์แบบสำหรับฉัน

ขั้นตอน (sudo โดยนัย):

cat /etc/timezone
rm -fv /etc/localtime
ln -s /usr/share/zoneinfo/Asia/Kolkata /etc/localtime
apt install -y --reinstall tzdata
/etc/init.d/rsyslog restart
tail -f /var/log/syslog
cat /etc/timezone

0

สิ่งที่เกี่ยวกับการประเมินเวลา utc ในเชลล์สคริปต์? กำหนดเวลาเชลล์สคริปต์ให้ทำงานทุกชั่วโมง ที่ด้านบนสุดของสคริปต์รับเวลา UTC จากคำสั่ง date หากไม่ใช่เวลา UTC ที่คุณต้องการให้ออก

สคริปต์นี้จะออกหากไม่ใช่เวลา 01.00 น.

#!/bin/bash
if [ $(date -u +"%H") != "01" ]; then
 exit 0
fi

0

คุณสามารถตั้งค่าตัวแปรสภาพแวดล้อม CRON_TZ ถ้างาน cron จะทำงานบนเซิร์ฟเวอร์ระยะไกลคุณอาจจะสังเกตเห็นว่าเปลือกที่ใช้โดย crontab คือการดวลจุดโทษ คุณสามารถตรวจสอบใน/ etc / crontab

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.