在 Linux 中使用 at 执行一次性 cron 任务
Cron
是计算机世界最知名的 UNIX 之一。即使是不管理 Linux 服务器的 IT 人员也听说过这个神秘的怪物“cron 作业”。Linux 管理员知道 cron 作业有无穷的用处。事实上,可以说该系统cron
是自动化热潮的早期先驱。如果你知道人类可能会忘记做某事,cron
那么答案就是 cron 作业。
然而,cron
重复才是最有效的,有时你不需要每小时、每天或每周运行一项作业。你只需要按计划执行一项作业,而设置闹钟来提醒自己似乎不符合 UNIX 的方式。你需要的是命令at
,这是一个小实用程序,你可以使用它来创建计划在未来特定时间运行的作业队列。
设置
在使用该at
命令之前,您必须有一个要在某个时间启动的 shell 脚本。像往常一样,您的脚本应该在文件顶部有一个“magic cookie”或“shebang”行,以设置要使用哪个 shell 来执行它。
对于此示例,创建一个简单的脚本,在中创建一个文件/tmp
:
#!/bin/sh
DATE=`date --utc +%s`
echo "hello world $DATE" | tee /tmp/at.log
exit 0
使脚本可执行,然后进行测试运行:
$ chmod +x test.sh
$ ./test.sh
查看脚本创建的文件的内容/tmp/at.log
:
$ cat /tmp/at.log
hello world 1588482185
安排作业
您可以使用时间戳或自然语言来安排作业。如果您使用自然语言或简单时间格式,则在指定时间之前不需要任何选项。
例如,要安排test.sh
立即运行,您只需使用关键字now
:
$ at now -f test.sh
warning: commands will be executed using /bin/sh
job 1 at Mon Feb 24 01:23:00 2020
$ cat /tmp/at.log
hello world 1588482620
您可以使用、、、或设置从现在开始的偏移量。minutes
hours
days
weeks
years
$ at now + 1 day -f test.sh
warning: commands will be executed using /bin/sh
job 2 at Tue Feb 25 01:27:00 2020
此years
关键字未记录在案,且seconds
不受支持。您也可以指定常见时间,例如midnight
、noon
和teatime
(即 16:00)。
简单时间也有效:
$ at 21:12 -f test.sh
warning: commands will be executed using /bin/sh
job 3 at Mon Feb 24 21:12:00 2020
要安排日历日期在特定时间,您必须使用选项-t
和任何符合POSIX 的时间格式。例如,使用 YYYYMMDDHHMM 格式:
$ at -t 202003141509 -f test.sh
warning: commands will be executed using /bin/sh
job 4 at Sat Mar 14 15:09:00 2020
[ 寻找更高级的系统自动化?从 Red Hat 的免费书籍《自动化企业》开始。]
管道
at
您可以通过 UNIX 管道发送命令:
$ echo "hello world" > /tmp/at.log | at now
warning: commands will be executed using /bin/sh
job 5 at Mon Feb 24 01:28:00 2020
$ cat /tmp/at.log
hello world
批处理作业
该batch
命令(或at -b
)会在系统资源允许的情况下尽早执行命令。如果您的系统负载很高,您可以使用batch
将您的作业排入队列,以便在有空闲 CPU 周期时运行。
$ echo "Cycles to spare" > /tmp/at.log | batch
warning: commands will be executed using /bin/sh
job 5 at Mon Feb 24 01:31:00 2020
查看您的队列
该atq
命令显示您的at
队列。它为您提供作业 ID、每个作业的计划运行时间、每个作业所属的队列(a
用于at
队列或b
用于batch
队列)以及队列所有者的用户名。队列所有者通常是您自己,除非您以 root 身份运行atq
,在这种情况下,您会看到所有用户的at
队列。
$ atq
2 Tue Feb 25 01:27:00 2020 a seth
3 Mon Feb 24 21:12:00 2020 a seth
4 Sat Mar 14 15:09:00 2020 a seth
5 Mon Feb 24 01:31:00 2020 b seth
您可以使用任意单个字符cz或AZ创建和命名自己的队列。a
和都是和 的b
保留名称,任何带有大写字母的队列都被视为作业。 名称按字母顺序排列的队列遵循和以递增的优先级运行。at
batch
batch
a
b
预览你的工作
当您将命令或脚本发送到 时at
,您的当前工作目录、环境(不包括BASH_VERSINFO
、DISPLAY
、EUID
、GROUPS
、SHELLOPTS
、TERM
和)和 umask 都会保留。如果您的命令需要特定的环境设置,那么您应该在将命令传递UID
给_
时设置这些设置,at
或者在脚本中覆盖它们。
要查看命令如何运行,请使用选项-c
和作业编号:
$ at -c 4
#!/bin/sh
# atrun uid=1006 gid=1006
# mail seth 0
umask 22
CPLUS_INCLUDE_PATH=/usr/lib64/qt/include; export CPLUS_INCLUDE_PATH
MANPATH=/usr/local/man:/usr/man:/usr/lib64/adoptopenjdk12.0.2/man; export MANPATH
KDE_MULTIHEAD=false; export KDE_MULTIHEAD
[...]
删除作业
您可以at
使用atrm
命令和作业 ID 从队列中删除待处理的作业。如果您不知道作业 ID,请先使用atq
查看队列。
$ atq
6 Fri Jan 01 00:00:00 2038 a seth
$ atrm 6
$ atq
使用 at 进行调度
该at
命令有点像较小的cron
系统。它对于一次性命令执行很有用,并且易于使用。如果您一直在使用cron
或sleep
来抵消命令的执行时间,请查看at
和batch
。
[需要了解更多有关 Linux 系统管理的知识?考虑参加Red Hat 系统管理课程。]