如何在 Linux 上使用 at 和 batch 来调度命令

如果你想安排一个只发生一次的 Linux 作业,那么 cron 就大材小用了。 at 系列命令就是您所需要的! 如果您只想在系统有空闲资源时运行进程,您可以使用批处理。

如何安排 Linux 作业

cron 守护进程维护 它在特定时间运行的作业列表. 这些任务和程序在预定时间在后台运行。 这为您安排需要重复的任务提供了极大的灵活性。 无论您是需要每小时运行一次任务、每天在特定时间运行,还是每月或每年运行一次,您都可以在 cron 中进行设置。

但是,如果您想安排一个任务只运行一次,这将无济于事。 当然,您可以在 cron 中设置它,但是您必须记住返回并删除 crontab 条目 任务执行后,很不方便。

使用 Linux,如果您正在为某个问题苦苦挣扎,那么几乎可以保证其他人也曾为它苦苦挣扎。 幸运的是,由于类 Unix 操作系统已经存在了很长时间,因此也很有可能有人已经为您的问题创建了解决方案。

对于上面概述的问题,他们有,而且它被称为。

安装 at 命令

我们必须在 Ubuntu 18.04 和 Manjaro 18.1.0 上安装(它已经安装在 Fedora 31 上)。

要在 Ubuntu 上安装,请使用以下命令:

sudo apt-get install at

这

安装完成后,您可以使用以下命令启动 at 守护程序:

sudo systemctl enable --now atd.service

这

在 Manjaro 上,您可以使用以下命令安装 at:

sudo pacman -Sy at

这

安装完成后,输入以下命令启动 at 守护进程:

sudo systemctl enable --now atd.service

这

在任何发行版上,您都可以键入以下命令以确保 atd 守护程序正在运行:

ps -e | grep atd

这

如何以交互方式使用 at 命令

要使用 at,您必须为其指定运行的日期和时间。 编写这些的方式有很大的灵活性,我们将在本文后面介绍。

但是,即使我们要以交互方式使用 at,您也必须预先提供日期和时间。 如果您在命令行中不包含任何内容,或者您​​键入的内容不是日期和时间,则 at 会以“乱码时间”响应,如下所示:

at
at banana

不正确的使用

日期和时间可以是明确的或相对的。 例如,假设您希望一分钟后执行命令。 at 知道“现在”是什么意思,所以你可以使用 now 并添加一分钟,如下所示:

at now + 1 minute

这

at 打印出一条消息和一个 at 提示,并等待您键入要安排的命令。 不过,首先,请考虑消息,如下所示:

这

它会在启动 sh shell 实例时告诉您,并将 运行里面的命令. 您的命令不会在 Bash shell 中执行,它与 sh shell 兼容,但具有更丰富的功能集。

如果您的命令或脚本尝试使用 Bash 提供的功能或工具,但 sh 没有,它们将失败。

很容易测试您的命令或脚本是否会在 sh 中运行。 使用 sh 命令启动 sh shell:

sh

这

命令提示符变为美元符号 ($),您现在可以运行命令并验证它们是否正确运行。

要返回 Bash shell,请键入 exit 命令:

exit

您不会从命令中看到任何标准输出或错误消息。 这是因为 sh shell 作为后台任务启动并且在没有任何类型的屏幕界面的情况下运行。

命令的任何输出(无论好坏)都会通过电子邮件发送给您。 它通过内部邮件系统发送给运行 at 命令的任何人。 这意味着您必须设置和配置该内部电子邮件系统。

许多(大多数)Linux 系统没有内部电子邮件系统,因为很少需要一个。 那些通常使用像这样的系统的人 发送邮件 或者 后缀. 如果您的系统没有内部电子邮件系统,您可以让脚本写入文件或将输出重定向到文件以添加日志记录。

如果该命令没有生成任何标准输出或错误消息,那么无论如何您都不会收到电子邮件。 许多 Linux 命令通过静默表示成功,因此在大多数情况下,您不会收到电子邮件。

现在,是时候在 at 中输入命令了。 对于此示例,我们将使用一个名为 sweep.sh 的小脚本文件,该文件删除 *.bak、*.tmp 和 *.o 文件。 键入命令的路径,如下所示,然后按 Enter。

这

出现另一个命令提示符,您可以添加任意数量的命令。 将命令放在单个脚本中并简单地从 at 中调用该脚本通常更方便。

按 Ctrl+D 表示您已完成添加命令。 在节目中 , 意思是 传输结束. 您会被告知作业编号以及作业计划运行的时间,如下所示:

确认

作业执行后,键入以下内容以检查您的内部邮件:

mail

这

如果没有邮件,你必须假设成功。 当然,在这种情况下,您可以检查并查看 *.bak 、 *.tmp 和 *.o 文件是否被删除以确认命令有效。

键入以下内容以再次运行整个过程:

at now + 1 minute

这

一分钟后,键入以下内容以重新检查您的邮件:

mail

这

嘿,我们有邮件! 要阅读第一条消息,请按 1,然后按 Enter。

我们收到了一封来自 at 的电子邮件,因为脚本中的命令生成了错误消息。 在此示例中,没有要删除的文件,因为当我们之前运行脚本时,它删除了它们。

按 D+Enter 删除电子邮件,按 Q+Enter 退出邮件程序。

日期和时间格式

在使用 at 的时间格式方面,您有很大的灵活性。 这里有一些例子:

上午 11:00 运行:

at 11:00 AM

明天上午 11:00 运行:

at 11:00 AM tomorrow

下周今天上午 11:00 运行:

at 11:00 AM next week

在这个时间、这一天、下周运行:

at next week

下周五上午 11:00 运行:

at 11:00 AM next fri

下周五此时运行:

at next fri

在下个月的这个日期上午 11:00 运行:

at 11:00 AM next month

在特定日期的上午 11:00 运行:

at 11:00 AM 3/15/2020

从现在开始运行 30 分钟:

at now + 30 minutes

从现在开始运行两个小时:

at now + 2 hours

明天这个时候运行:

at tomorrow

在星期四的这个时间运行:

at thursday

凌晨 12:00 运行:

at midnight

下午 12:00 运行:

at noon

如果你是英国人,你甚至可以安排一个命令在下午茶时间(下午 4 点)运行:

at teatime

查看作业队列

您可以键入 atq 命令来查看计划作业的队列,如下所示。

从输出

对于队列中的每个命令,atq 显示以下信息:

作业编号
约定的日期
计划的时间
将作业放入队列。队列标记为“a”、“b”等。 您在 at 中安排的正常任务进入队列“a”,而您通过批处理安排的任务(本文后面将介绍)进入队列“b”。
安排工作的人。

在命令行上使用 at

您不必以交互方式使用 at; 您也可以在命令上使用它。 这使得在脚本内部使用变得更容易。

您可以将命令通过管道输入 at,如下所示:

echo "sh ~/sweep.sh" | at 08:45 AM

一个

作业由 at 接受和调度,作业号和执行日期与以前一样报告。

将 at 与命令文件一起使用

您还可以将一系列命令存储在文件中,然后将其传递给 at。 这可以是命令的纯文本文件——它不必是可执行脚本。

您可以通过以下方式使用 -f(文件)选项将文件名传递给 at:

at now + 5 minutes -f clean.txt

一个

如果将文件重定向到以下位置,您可以获得相同的结果:

at now + 5 minutes 

一个

Removing Scheduled Jobs from the Queue

To remove a scheduled job from the queue, you can use the atrm command. If you want to see the queue first to find the number of the job you want to remove, you can use atq . Then, use that job number with atrm, as shown below:

atq
atrm 11
atq

如何查看作业的详细视图

正如我们之前提到的,您可以将作业安排到很远的将来。 有时,您可能会忘记工作将要做什么。 atq 命令显示队列中的作业,但不显示它们将要做什么。 如果要查看作业的详细视图,可以使用 -c (cat) 选项。

首先,我们将使用 atq 查找作业编号:

atq

从输出

现在,我们将使用带有 -c 选项的作业编号 13:

at -c 13

这

以下是我们获得的有关该工作的信息的细分:

第一行:这告诉我们命令将在 sh shell 下运行。
第二行:我们看到命令将以 1000 的用户 ID 和组 ID 运行。这些是运行 at 命令的人的值。
第三行:收到任何电子邮件的人。
第四行: 用户掩码 是 22。这是用于设置此 sh 会话中创建的任何文件的默认权限的掩码。 从 666 中减去掩码,得到 644(rw-r--r-- 的八进制等价物)。
剩余数据:大部分是环境变量。

从输出

测试的结果。 测试检查以确保可以访问执行目录。 如果不能,则会引发错误,并放弃作业执行。
要执行的命令。 列出了这些,并显示了计划的脚本的内容。 请注意,尽管我们上面示例中的脚本是为在 Bash 下运行而编写的,但它仍将在 sh shell 中执行。

批处理命令

批处理命令 操作类似 到 at 命令,但有三个显着差异:

您只能以交互方式使用批处理命令。
不是将作业安排在特定时间执行,而是将它们添加到队列中,当系统的平均负载低于 1.5 时,批处理命令会执行它们。
由于上述原因,您永远不会使用批处理命令指定日期和时间。

当您使用批处理命令时,您可以按名称调用它,不带命令行参数,如下所示:

batch

这

接下来,就像使用 at 命令一样添加任务。

控制对 at 命令的访问

at.allow 和 at.deny 文件控制谁可以使用 at 系列命令。 它们位于 /etc 目录中。 默认情况下,只有 at.deny 文件存在,它是在安装 at 时创建的。

以下是它们的工作原理:

at.deny:列出不能使用 at 来安排作业的应用程序和实体。
at.allow:列出可以使用 at 来安排作业的人员。 如果 at.allow 文件不存在,则 at 仅使用 at.deny 文件。

默认情况下,任何人都可以使用 at。 如果您想限制谁可以使用它,请使用 at.allow 文件列出可以使用的人。 这比将无法使用 at 的每个人添加到 at.deny 文件更容易。

at.deny 文件如下所示:

sudo less /etc/at.deny

这

该文件列出了操作系统中不能使用的组件。 出于安全原因,其中许多都被阻止这样做,因此您不想从文件中删除任何内容。

现在,我们将编辑 at.allow 文件。 我们将添加 dave 和 mary,但不允许其他人使用 at。

首先,我们输入以下内容:

sudo gedit /etc/at.allow

这

在编辑器中,我们添加两个名称,如下图,然后保存文件。

如果其他人试图使用 at,他会被告知他没有权限。 例如,假设名为 eric 的用户键入以下内容:

at

他会被拒绝,如下图所示。

同样,eric 不在 at.deny 文件中。 一旦您将任何人放入 at.allow 文件中,任何人和其他所有人都将被拒绝使用 at。

非常适合一次性

如您所见,at 和 batch 都是您只需要运行一次的任务的理想选择。 再次作为快速回顾:

当你需要做一些不是常规过程的事情时,用 at 来安排它。
如果您只想在系统负载足够低时运行任务,请使用批处理。