cron job

最後更新: 2019-09-13

目錄

 


Cron jobs 設定的格式

 

Format

# 分   時  日    月   週      指令
m      h   d    M    w      cmd

每一個 field 的 value

field          allowed values
-----          --------------
minute         0-59
hour           0-23
day of month   1-31
month          1-12 (or names, see below)
day of week    0-7 (0 or 7 is Sun, or use names)
  • any              *
  • Lists            2,5,9,18-24
  • every n       */n
  • steps          "1-9/2" is the same as "1,3,5,7,9"

Notes(dom & dow)

If both 'day of month' and 'day of week' are restricted (i.e. 不是 "*" )

The command will be run when either field matches the current time.

"40 8 1,15 * 7" 相當於每月的 1, 15 號行. 另外每星期日也會行.

 


Shell 與 Path

 

/etc/crontab

SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
MAILTO=root

 


Add cron job by echo

 

# 用 "-e" 加 remark

echo -e "# daily report \n 1 10 * * * $MyScript" | crontab -

# 在 shell 入面行

echo  \"    1 * * * *    wget -O    -     <URL>     |   bash;   \"  |   crontab -  ;

 


crontab utc or local time

 

 * Not all versions of cron support running jobs using a time zone(TZ) other than the system's

 * does not support per-user timezones.

如果 cron 支援 TZ

# This file has been deprecated: /etc/default/cron

可以在 /etc/init/cron.conf 加入

TZ="UTC"

支不支援請看:

man 5 crontab

# 如果系統不支援, 那就要靠 system 的 timezone 設定了

/etc/timezone

# Also be sure to restart cron as it won’t pick up the timezone change

/etc/init.d/cron restart

 


"@"  commands

 

@

  • @reboot        Run once, at startup.
  • @yearly         Run once a year, "0 0 1 1 *".
  • @annually      (same as @yearly)
  • @monthly       Run once a month, "0 0 1 * *".
  • @weekly        Run once a week, "0 0 * * 0".
  • @daily           Run once a day, "0 0 * * *".
  • @midnight      (same as @daily)
  • @hourly         Run once an hour, "0 * * * *".

Usage

# sync time
@reboot         /usr/sbin/ntpdate stdtime.gov.hk > /dev/null 2>&1
3 * * * *       /usr/sbin/ntpdate stdtime.gov.hk > /dev/null 2>&1

 


run-parts

 

The run-parts script loops over all executable files in this directory.

SYNOPSIS

run-parts DIRECTORY

opt:

--test       # print the names of the scripts which would be run

--verbose  # print the name of each script to stderr before running

--report    # similar to --verbose, but only prints the name  of  scripts  which  produce  output.

Centos 6:

daily, weekly, monthly 由 anacrontab 掌管了 !!

/etc/anacrontab

# period in days   delay in minutes   job-identifier          command
1                  5                  cron.daily              nice run-parts /etc/cron.daily
7                  25                 cron.weekly             nice run-parts /etc/cron.weekly
@monthly           45                 cron.monthly            nice run-parts /etc/cron.monthly

# delay in minutes "0" = no delay. 它是設定 anacron 的 延遲
# (用於錯開 cron 的 jobs)
# 5 + 45 min random delay
RANDOM_DELAY=45

# 03:00-22:00
START_HOURS_RANGE=3-22     

Centos 5:

/etc/crontab

01  *  *  *  *   root      run-parts /etc/cron.hourly   <==每小時
02  4  *  *  *   root      run-parts /etc/cron.daily    <==每天
22  4  *  *  0   root      run-parts /etc/cron.weekly   <==每週日
42  4  1  *  *   root      run-parts /etc/cron.monthly  <==每個月 1 號

Debian:

apt-get install anacron

/etc/crontab

# m h dom mon dow user  command
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )

 


anacron

 

它是由 cron 發動 /etc/cron.hourly/0anacron

It execute commands periodically, with a frequency specified in days.

After the command exits, Anacron records the date in a special timestamp file for that job,

so it can know when to execute it again.

(Unlike cron, anacron does not assume that the machine is running continuously.)

The period is specified in days (Only the date is used for the time calculations. The hour is not used.)

# Directory is used by Anacron for storing timestamp files

/var/spool/anacron

原理

cron -> /etc/cron.hourly/0anacron -> anacron -s

-s     Serialize execution of jobs. 

        Anacron will not start a new job before the previous one finished.

Configuration File

/etc/anacrontab

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root

# the maximal random delay added to the base delay of the jobs
RANDOM_DELAY=10

# 只有 03:00 ~ 22:00 才行 anacrontab 的 cron jobs
START_HOURS_RANGE=3-22

# These replace cron's entries
#period in days   delay in minutes   job-identifier   command
1                 5                  cron.daily       run-parts --report /etc/cron.daily
7                 10                 cron.weekly      run-parts --report /etc/cron.weekly
@monthly          15                 cron.monthly     run-parts --report /etc/cron.monthly

RANDOM_DELAY

Add a randomly delay between 0 ~ 10 minutes to the user defined delay.

1                 5                  cron.daily       run-parts --report /etc/cron.daily

delay will be 5 minutes + RANDOM_DELAY for cron.daily

START_HOURS_RANGE

當 miss 在 START_HOURS_RANGE 時間執行(ie. 如那段時間關機了),

那就會略過那次執行 (不論是 daily, weekly, monthly 的 jobs)

i.e.

grep zfs-auto-snap /var/log/messages

Mar 26 03:39:02 tim zfs-auto-snap: ...
Mar 27 03:31:02 tim zfs-auto-snap: ...
Mar 28 03:33:02 tim zfs-auto-snap: ...
Mar 29 03:19:02 tim zfs-auto-snap: ...
Mar 30 03:33:02 tim zfs-auto-snap: ...

job-identifier

name for the job’s timestamp file

ls -l /var/spool/anacron

total 12
-rw-------. 1 root root 9 Feb  9 03:13 cron.daily
-rw-------. 1 root root 9 Feb  9 03:07 cron.monthly
-rw-------. 1 root root 9 Feb  9 03:33 cron.weekly

cat /var/spool/anacron/cron.daily

20220209

 


E-Mail

 

所有在 cron job 內行的 cmd 的 stdout 及 stderr 都會送到指定郵箱.

# If MAILTO is defined but empty (MAILTO=""), no mail will be sent. 

# Otherwise mail is sent to the owner of the crontab.

MAILTO=""

MAILTO

strings /usr/sbin/cron | grep mail

mailed %d byte%s of output but got status 0x%04x from MTA
bad mailto
/usr/sbin/sendmail

Centos 6

  • MAILTO
  • MAILFROM

 


同一時間的 cron job 係 parallel 的

 

The tasks listed in cron will run in parallel,

2 4 * * * /path/to/command1
2 4 * * * /path/to/command2

如果想行完 command1 再行 command2 就要寫成

# Use a semicolon to run command2 after command1 has completed
2 4 * * * /path/to/command1; /path/to/command2

 

 


很可怕的 Options "-r"

 

current crontab to be removed

 


Run cron jobs permission

 

cron.allow 及 cron.deny 係用來 control 某一個 user 能否用 "crontab"

亦即是說設定好的 jobs 會繼續行的 !!

  • /etc/cron.allow

If the file cron.allow exists, only users listed in it are allowed to use cron

  • /etc/cron.deny

* If cron.allow does not exist, users listed in cron.deny are not allowed to use cron.

* If both files exist then cron.allow takes precedence

* In the case where neither file exists, the default on current Ubuntu is to allow all users to run jobs with crontab.

   (but not some other Linux and UNIX systems)

測試

crontab -u www-data -l

The user www-data cannot use this program (crontab)

per user cron jobs file

/var/spool/cron/crontabs/username

Remark

為了令系統更安全, 行以下 cmd 會不錯

touch /etc/cron.allow /etc/cron.deny

Other User run cron jobs

行 cron jobs 的那個 user 要有 home directory

Dec  4 15:34:01 assp1 CROND[14606]: (CRON) ERROR chdir failed (/home/assp): No such file or directory

 


Config file Permission(BAD FILE MODE)

 

在 Centos6 上

Dec 27 15:46:01 mail crond[23299]: (root) BAD FILE MODE (/etc/cron.d/response)

一定要 permission 0644

ie.

chmod root: /etc/cron.d /etc/cron.d/*
chmod 755 /etc/cron.d
chmod 644 /etc/cron.d/*

 


Do something on last day on month

 

#!/bin/bash

root-path=/home/vhosts/datahunter.org

nday=`date --date='1 day' +%d`
if [[ $nday == 01 ]];
then
    date
    /usr/bin/php $root-path/cron.php >> $root-path/cron.log 2>&1
fi

 


Troubleshoot

 

[1] Debug $PATH Variable

system 's crontab

/etc/crontab

* * * * * root /usr/bin/env &> /tmp/env_dump.txt

daily 's crontab

/etc/cron.daily/env_dump   # chmod 750 /etc/cron.daily/env_dump

/usr/bin/env &> /tmp/env_dump.txt

 * cron.daily 係用 /etc/anacrontab 發動

user 's crontab

$PATH in user crontab(crontab -l) is different from system crontab (/etc/crontab)

PATH=/sbin:/bin:/usr/sbin:/usr/bin

* * * * * env &> /tmp/env_dump.txt

 


Add crontab from cli

 

應用了 "crontab [-u user] file"

 

e.g.

crontab -l > mycron

cat >> mycron << EOF
# fix ftp permission
* * * * *    /root/scripts/fix-ftp-permission.sh
EOF

crontab mycron

rm -f mycron

 


Doc

 

詳見 man 5 crontab

 

 

Creative Commons license icon Creative Commons license icon