为您服务—Linux 的作业调度
借鉴通信领域,服务可以分为两大类:即时服务和延时服务。即时通信服务包括电话会议、在线聊天等;而延时服务包括电子邮件和传真。本专栏概述了 Linux at 实用程序,该实用程序允许延时(或计划)执行程序。
当然,大多数程序需要以立即执行、立即执行模式启动。然而,通常希望甚至可能需要计划在特定时间执行程序(或在古老的 Geek 术语中称为作业),这出于各种实际原因。考虑以下任何一种情况:
一个开发团队开发了一个脚本,该脚本重建其源代码树并更新应用程序的暂存区。该脚本完全自动化,但非常耗时且占用大量 CPU 资源。实际上,该团队决定应将此作业安排在深夜运行,那时它与较少的用户和进程竞争资源。
一台高质量的彩色打印机/绘图仪在正常工作时间内需求量很大。项目经理每周多次使用打印机重新打印一份快速演进的项目计划,该计划超过 200 页。为了避免在打印机使用高峰期占用打印机,项目经理决定应在清晨(大多数用户处于非活动状态之前)运行打印作业。
项目负责人希望在下周五下午 4:00 举行的会议前四小时,通过电子邮件向参与的工作人员发送会议提醒/议程备注。
系统管理员 (SA) 一直收到关于工作日开始时系统性能极差的报告。性能下降的原因尚不明显。系统管理员没有梳理大量的系统日志,而是决定计划执行一个程序来捕获系统负载信息。该作业将在第二天上午 9:00 的每个五分钟执行一次。
用于更新本地数据仓库的外部数据源每周五晚上 6:00 可用。如果长时间的更新过程未成功完成,则在一小时后重试。否则,将重新安排在下周五执行。
上述每种情况中概述的调度要求都可以通过 at 实用程序来解决。此外,这些情况代表了 at 最常见应用领域的广泛范围。at 实用程序非常适合在系统上用户处理需求较少时执行 CPU 密集型任务,在通常更容易获得资源的时间利用稀缺资源,在特定时间分发提醒,执行需要在用户无意主动连接到系统时运行的作业,以及执行依赖于资源在特定时间变为可用的作业。
at 实际上是一组相关程序,允许 Linux 用户调度和管理延时作业的执行。如果您认为 at 仅适用于非交互式任务,那么您是对的。通过 at 调度的程序应能够作为后台进程运行,因为 at 不会将用户显示设备与正在执行的作业关联。用户通常发现 at 命令行界面非常直观。然而,它也足够富有表现力,可以满足任何可以想象的调度要求。在介绍命令行界面的示例之前,让我们总结一下 at 提供的基本服务。它允许在特定时间/日期调度作业的执行,显示有关当前计划作业的信息,取消当前计划的作业,以及管理有权使用 at 程序的用户的列表。
此处提供的示例假设您基本熟悉 shell 命令执行和 Bourne shell 语法。每个示例都在 Red Hat Linux 7 (2.3 内核) 平台上进行了测试。但是,我希望这些示例在所有常见发行版上都能按原样工作。
显然,at 提供的最基本功能是在稍后的时间调度程序的执行。at 程序通常安装在 /usr/bin/at 中,其基本命令行语法如下:
at [options] TIME [DATE] < bourne-shell-file
此语法暗示以下调用 at 的替代方法也有效:
cat bourne-shell-file | at [options] TIME [DATE] at [options] TIME [DATE] ## Anything normally accepted by the bourne shell ## interpreter will be accepted. Terminate with ## Ctrl-D (^d) statement 1 statement 2 statement 3 statement 4 ^d这里的第一个重要细节是时间和日期的正确表示法。日期始终是可选的。当从命令行中省略日期时,日期被假定为指定时间将发生的第二天,即今天或明天。例如,如果时间指定为下午 1:30,而现在已经是下午 4:30,则作业将安排在第二天下午 1:30 执行。at 接受扩展 POSIX.2 标准的时间/日期表示法。该表示法可能在您的安装的 /usr/doc 目录下的名为 timespec 的文件中记录。
让我们通过一些示例来学习。表 1 中的时间/日期规范示例将让您很好地了解 at 程序将接受什么。
如图所示,at 程序接受相当丰富且直观的表示法。它尝试通过从左到右解析其命令行参数来解释指定的时间/日期。如果其时间/日期规范被违反,则会显示“Garbled time”(时间格式错误)错误诊断,并且程序终止。它通常会提供简明的提示,说明它为何出现问题。例如,查看以下调用尝试:
$ at 6am Mar 32 Error in day of month. Last token seen: 32 Garbled time $
以下调用成功安排了一个作业。考虑上面为本次提交概述的第三种使用场景:
$ at 1pm friday warning: commands will be executed using /bin/sh STAFF="moe larry curly" cd mail mail -s"Meeting Reminder" $STAFF < friday_agenda.txt ^d job 6 at Fri Apr 13 13:00:00 2001 $如果您密切关注,一些问题应该开始形成。计划作业的标准输出和标准错误流是否会被捕获到某个地方?所有标准输出和标准错误诊断都由 at 服务(/usr/sbin/atd 程序)捕获,并在计划作业完成时通过电子邮件发送给提交用户。电子邮件将显示主题标题,例如:
主题:来自您的作业 17 的输出
我们是否仅限于调度 Bourne shell 脚本?正如上面示例的反馈所示,at 使用系统 Bourne shell 程序 (/bin/sh) 来解释用户提供的程序语句。因此,您在 Bourne shell 提示符下键入的任何内容都是有效的,包括 Bourne shell 脚本或启动您环境中找到的任何可执行文件,甚至是不同的语言解释器。查看以下示例,了解如何调度 Perl 脚本的执行:
$ at 6pm tomorrow warning: commands will be executed using /bin/sh perl /home/moe/perls/script1.pl ^d job 28 at Wed Apr 18 18:00:00 2001 $
计划进程分配了哪些系统用户/组?作业提交环境的哪些属性被保留并延续到作业执行环境?对于大多数用户来说,了解实用程序如何在幕后提供服务通常不感兴趣。但是,在 at 的情况下,实用程序实际执行的操作示例非常容易理解,并且展示了什么是可能的,什么是不可能的以及原因。每个计划作业都会生成一个 Bourne shell 脚本,该脚本放置在 /var/spool/at/ 目录下。这些生成的脚本由以下部分组成:
程序注释,提供有关作业完成时通知哪个用户的一些线索。此外,还指定了分配给作业的有效用户 ID 和组 ID。
umask 设置决定了应如何创建新文件/目录。
提交作业时环境 变量分配的完整列表(与显示设备相关的变量除外,例如 TERM 和 DISPLAY)。
当前目录更改为用户计划任务时的目录。如果作业执行时该目录不存在,则作业中止并发送电子邮件通知。
附加到提交给 at 的程序文本的副本。
考虑到这一点,清单 1 是代表我们的用户 Moe 计划的作业生成的脚本的缩写示例。要完成我们对 at 程序的命令行界面描述,请参阅表 2,了解其一些更有用的命令行选项。
以下是使用 at 调度作业的另一个示例:
$ at -mf /home/curly/shells/program1 6pm tomorrow warning: commands will be executed using /bin/sh job 29 at Thu Apr 12 18:00:00 2001 $
还有两个程序与基本的 at 程序相关联:atq 和 atrm。正如您可能猜到的,atq 列出当前计划的作业,而 atrm 取消一个或多个指定的作业。虽然 root 用户能够查看和取消任何和所有作业,但非 root 用户只能查看和取消他们计划的作业。
清单 2 显示了 root 用户查看的 atq 显示的输出示例(我插入了字段标签以提高可读性—不幸的是,Linux 的 atq 实现没有提供它们)。
Rank 是用于向其他 at 程序标识计划作业的唯一序列值。除了计划时间和提交用户之外,还列出了队列值。除非用户另有指定,否则作业将放置在 “a” 队列中。(参考在线手册页,了解向 at 程序指定备用队列值的含义—它本质上控制作业的运行时优先级。)atq 在队列字段中使用 “=” 值来限定当前正在运行的作业。因此,表 3 中看到的作业 17 当前正在执行。
如果用户提交了一个作业,然后意识到时间和/或程序不正确怎么办?atrm 实用程序可用于删除一个或多个计划作业。例如,root 用户可以使用以下命令取消表 3 中列出的第一个和第二个作业:
atrm 18 19
atrm 不提供反馈。随后的 atq 列表将显示如清单 3 所示的队列。
如果您尝试使用 at 程序之一时产生以下诊断信息:“You do not have permission to use at”(您没有使用 at 的权限),则需要联系您的本地系统管理员 (SA)。Linux 系统管理员可以非常灵活地管理 at。
正如您可能预期的那样,root 用户拥有使用 at 实用程序的绝对权限,并且可以将相同的权限授予非 root 用户。两个系统文件 /etc/at.allow 和 /etc/at.deny 控制对 at 实用程序的访问。表 3 显示了它们的存在和内容如何确定给定系统上用户的权限。
请注意,如果 /etc/at.allow 文件存在,则 /etc/at.deny 将被完全忽略。用户在其 Linux 登录名中标识,每个用户在单独的行上显示。at 不提供命令行实用程序来控制这些文件的内容。系统管理员通常选择他们喜欢的文本编辑器并根据需要手动编辑文件。不过,考虑到更改的频率可能不高,这几乎不能被认为是缺点。
总而言之,非 root 用户可以被显式或隐式地分配或拒绝使用 at 的权限。系统管理员可以选择通过排除或包含来管理对 at 的访问。选择最适合您特定安装的方法。例如,高度敏感的生产站点可能应该基于包含进行管理(即,除非明确授予权限,否则非 root 用户没有权限—/etc/at.allow 文件存在)。相反,Linux 默认配置可能适用于大多数开发/测试环境(即,除非明确拒绝,否则非 root 用户具有权限—/etc/at.allow 不存在,并且 /etc/at.deny 具有零个或多个条目)。
总的来说,at 程序提供了一种直观的方式来管理应用程序的延时执行。尽管 at 实用程序简单而有用,但 Linux 管理员和开发人员通常会忽略它。还存在其他不太常用的 at 命令行选项,我选择在此处不介绍。我鼓励您通过在您喜欢的 shell 提示符下键入 man at 来查看 at 手册页,以查看所有详细信息。此外,大多数 Linux 概述书籍都提供对 at 和类似程序的一些介绍,例如 O'Reilly 的 Linux in a Nutshell,作者是 Ellen Siever 等人。
