使用 UNIX at 工具计划一次性命令
Cron 很好用,但别忘了它的表亲 at
。
当我第一次开始使用 Linux 时,感觉就像被扔进了 UNIX 池的深水区。 你需要大量使用命令行,以及你的发行版附带的所有标准实用程序和服务。 自那时以来,很多事情都发生了变化,现在,你可以使用标准的 Linux 桌面,甚至无需打开终端或使用旧的 UNIX 服务。 即使作为系统管理员,如今,你通常也处于某些核心服务之上的几个抽象层。
我说这一切是为了指出,对于我们这些老手来说,很容易理所当然地认为我们周围的每个人都天生知道我们使用的所有命令行工具。 然而,即使我已经使用 Linux 20 年了,我仍然一直在学习新的(对我而言)命令行工具。 在这个“回归基础”系列文章中,我计划介绍一些 Linux 新手可能从未使用过的命令行工具。 对于那些更高级的用户,我将分散这个系列,所以你可以期待未来的文章会更具技术性。 在本文中,我将描述如何使用 at
实用程序来计划在稍后日期运行的作业。
at
与 Cron
at
是那些不太常被讨论的命令之一。 当人们谈论计划命令时,通常 cron 获得的关注最多。 Cron 允许你计划定期运行的命令。 使用 cron,你可以以最快每分钟一次或最慢每天、每周、每月甚至每年一次的频率运行命令。 你还可以定义更复杂的规则,例如,命令每五分钟、每个工作日、每隔一小时以及许多其他组合运行。 系统管理员有时会使用 cron 来计划本地脚本每分钟收集指标或计划备份。
另一方面,虽然 at
命令也允许你计划命令,但它的用途与 cron 完全不同。 虽然 cron 让你计划定期运行的命令,但 at
让你计划仅在未来特定时间运行一次的命令。 这意味着 at
满足的需求与 cron 不同,通常更迫切。
at
在某个时候,at
命令在大多数 Linux 发行版上都是标配,但如今,即使在服务器上,你可能也会发现自己需要显式安装 at
软件包。 安装后,使用 at
最简单的方法是在命令行上键入它,后跟你希望命令运行的时间
$ at 18:00
at
命令还可以接受多种不同的时间格式。 例如,它理解 AM 和 PM 以及诸如“tomorrow”(明天)之类的词,因此你可以用相同的命令替换上面的命令
$ at 6pm
而且,如果你想在明天同一时间运行相同的命令,则可以使用
$ at 6pm tomorrow
按下回车键后,你将进入交互式 shell
$ at 6pm tomorrow
warning: commands will be executed using /bin/sh
at>
在交互式 shell 中,你可以输入你想要在该时间运行的命令。 如果你想运行多个命令,请在每个命令后按回车键,并在新的 at>
提示符下键入命令。 完成输入命令后,在空的 at>
提示符下按 Ctrl-D 以退出交互式 shell。
例如,假设我注意到一台特定的服务器在过去两天早上 5:10 左右出现了大约五分钟的问题,到目前为止,我在日志中没有看到任何内容。 虽然我可以早点醒来并登录服务器,但我可以编写一个简短的脚本,从 ps
、netstat
、tcpdump
和其他命令行工具收集几分钟的数据,这样当我醒来时,我可以查看它收集的数据。 由于这是一次性的,我不希望使用 cron 计划某些东西,并冒着忘记它并让它每天运行的风险,所以这就是我使用 at
设置它的方式
$ at 5:09am tomorrow
warning: commands will be executed using /bin/sh
at>
at> /usr/local/bin/my_monitoring_script
然后我会按 Ctrl-D,shell 将退出并显示此输出
at> <EOT>
job 1 at Wed Sep 26 05:09:00 2018
管理 at
作业
一旦你计划了 at
作业,能够调出队列中所有 at
作业的列表会很有用,这样你就知道正在运行什么以及何时运行。 atq
命令列出当前的 at
队列
$ atq
1 Wed Sep 26 05:09:00 2018 a kyle
第一列列出了 at
分配给每个作业的编号,然后列出了作业将运行的时间以及将作为哪个用户运行。 假设在上面的示例中,我意识到我犯了一个错误,因为我的脚本将无法作为普通用户运行。 在这种情况下,我想使用 atrm
命令删除作业编号 1
$ atrm 1
如果我再次运行 atq
,我会看到该作业不再存在。 然后我可以 sudo
提升到 root 用户,并使用 at
命令再次计划该作业。
at
单行命令
虽然 at
支持交互模式,但你也可以在一行中将命令通过管道传递给它。 因此,例如,我可以使用以下命令计划上面的作业
$ echo /usr/local/bin/my_monitoring_script | at 5:09am tomorrow
结论
如果你不知道 at
的存在,你可能会发现自己想出各种复杂和曲折的方法来计划一次性作业。 更糟糕的是,你可能需要设置闹钟,以便你可以格外早起并登录到有问题的服务器。 当然,如果你没有闹钟,你可以使用 at
$ echo "aplay /home/kyle/alarm.wav" | at 7am tomorrow