关于各种系统中定时任务的总结

6 minute

Unix 下的定时任务

unix 系的系统都可以通过 crontab 来执行定时任务, 一个很好地帮助我们编写 crontab 的网址: crontab.guru

Crontab 规则

1*/1 * * * * cmd

5个单元:

分钟(0-59) 小时(0-23 日期(1-31) 月份(1-12) 星期几(0-6, 其中 0 代表星期日)

Crontab 实用例子

每分钟执行一次:

1* * * * * cmd ## or: */1 * * * * cmd

每天早上 6 点 10 分执行一次:

110 6 * * * cmd

每两个小时执行一次:

10 */2 * * * cmd

在 1 月 1 日早上 4 点执行一次:

10 4 1 1 * cmd

Crontab 环境变量问题

crontab 不会使用在 .bashrc 之类的文件中定义的变量, 别名和函数。

解决方法是在 crontab 中通过 bash -lic "{your_cmd}" 调用脚本或命令, 同时如果调用了 python 之类脚本且脚本里还使用了类似 os.system() 之类的系统调用命令, 则 os.system() 里也要通过 bash -lic "{your_cmd}" 调用脚本或命令。

另外, 即使使用了 -lic, crontab 中除命令外的路径都需要使用绝对路径。

-i 将开启一个 interactive shell, 执行 ~/.bashrc, 如需使用别名, 则需添加使用该参数, 因为 alias 在 non-interactive shell 中默认是被禁用的。

-l 将开启一个 login shell, 执行 ~/.profile

PS: 部分命令可能即使添加了 -lic 也无法检索到, 比如一些装在 /usr/local/bin 下的可执行文件, 那是因为这些路径没有被你加入 PATH 中~

记一个正确使用示例:

10 0 * * 1 /usr/bin/zsh -lic "python3 /root/Codes/saver.py -ft 1"

其中注意 zsh 需要使用绝对路径, 因为不在 -lic 指定的命令中; python3 无需使用绝对路径, 因为它处于 -lic 指定的命令中; 而 saver.py 虽然处在 -lic 指定的命令中, 但是它不是命令, 所以还是需要使用绝对路径。

Crontab 配置文件

配置文件在:/var/spool/cron/{用户名}

每个用户对应一个 crontab 配置, 所以在 crontab 语句中使用 ~ 是可以的。

PS: 在 mac 中, 该文件对用户不可见。

Crontab 日志位置

Centos: /var/log/cron

Ubuntu / Debian: 默认情况下被打印到: /var/log/syslog, 通过如下命令查看:

1grep CRON /var/log/syslog

MacOS: 默认情况下被禁用, 建议使用 mail 来确定是否执行成功。

Crontab 邮件位置

每个 crontab 任务执行之后都会发送一封邮件给用户, 位置在 /var/mail/{用户名}

通过该邮件可以方便地进行 debug。

如果没有该服务, 可以通过如下命令解决:

1sudo apt install postfix -y
2systemctl start postfix

Windows 下的定时任务

windows 下一般可以通过自带的 SCHTASKS 来执行定时任务。

SCHTASKS 使用规则

 1SCHTASKS /parameter [arguments]
 2
 3Parameter List:
 4    /Create         Creates a new scheduled task.
 5
 6    /Delete         Deletes the scheduled task(s).
 7
 8    /Query          Displays all scheduled tasks.
 9
10    /Change         Changes the properties of scheduled task.
11
12    /Run            Runs the scheduled task on demand.
13
14    /End            Stops the currently running scheduled task.
15
16    /ShowSid        Shows the security identifier corresponding to a scheduled task name.
17
18    /?              Displays this help message.

查询某个操作的具体用法:

1schtasks /create /?
2
3SCHTASKS /Create [/S system [/U username [/P [password]]]]
4    [/RU username [/RP password]] /SC schedule [/MO modifier] [/D day]
5    [/M months] [/I idletime] /TN taskname /TR taskrun [/ST starttime]
6    [/RI interval] [ {/ET endtime | /DU duration} [/K] [/XML xmlfile] [/V1]]
7    [/SD startdate] [/ED enddate] [/IT | /NP] [/Z] [/F] [/HRESULT] [/?]
8
9    ...

SCHTASKS 实用例子

每 30 分钟运行一次

1schtasks /create /sc minute /mo 30 /tn "{task_name}" /tr "{task}"

阅读可知, /sc 是指定频率的单位:

1/SC   schedule     Specifies the schedule frequency.
2                    Valid schedule types: MINUTE, HOURLY, DAILY, WEEKLY,
3                    MONTHLY, ONCE, ONSTART, ONLOGON, ONIDLE, ONEVENT.

/mo, 在 /sc 的基础上, 指定大小(可以的情况下使用, 如 MINUTE 可以, 而 ONSTART 不可以):

 1Modifiers: Valid values for the /MO switch per schedule type:
 2    MINUTE:  1 - 1439 minutes.
 3    HOURLY:  1 - 23 hours.
 4    DAILY:   1 - 365 days.
 5    WEEKLY:  weeks 1 - 52.
 6    ONCE:    No modifiers.
 7    ONSTART: No modifiers.
 8    ONLOGON: No modifiers.
 9    ONIDLE:  No modifiers.
10    MONTHLY: 1 - 12, or
11             FIRST, SECOND, THIRD, FOURTH, LAST, LASTDAY.
12
13    ONEVENT:  XPath event query string.

/tn, 即 “task name”, 注意是 unique 的, 不能与其它任务重名。

/tr, 即 “task run”, 指定任务, 即一个可执行的程序, 如 exe, bat。

开机启动程序

需要通过管理员模式运行以下命令:

1schtasks /create /tn "{task_name}" /sc onlogon /tr "{task}"

每天 22:00:00 执行一次

1schtasks /create /tn "{task_name}" /sc daily /st 22:00:00 /tr "{task}"

阅读可知, /st 是用于指定执行的具体时刻:

1/ST   starttime    Specifies the start time to run the task. The time
2                    format is HH:mm (24 hour time) for example, 14:30 for
3                    2:30 PM. Defaults to current time if /ST is not
4                    specified.  This option is required with /SC ONCE.

删除定时任务

1schtasks /delete /tn "{task_name}"

由于任务名是唯一的, 所以通过 /tn 指定任务名即可删除任务。