shell脚本控制——定时运行作业

在使用脚本时,你也许希望脚本能在以后某个你无法亲临现场的时候运行。Linux系统提供了多个在预选时间运行脚本的方法:at命令、cron表以及anacron。每种方法都使用不同的技术来安排脚本的运行时间和频率。接下来将依次介绍这些方法。

1.使用at命令调度作业

at命令允许指定Linux系统何时运行脚本。该命令会将作业提交到队列中,指定shell何时运行该作业。

at的守护进程atd在后台运行,在作业队列中检查待运行的作业。很多Linux发行版会在启动时运行此守护进程,但有些发行版甚至都没安装这个软件包。如果你的Linux属于后一种情况,则可以自行安装,软件包的名字如你所料,就是at。

atd守护进程会检查系统的一个特殊目录(通常位于/var/spool/at或/var/spool/cron/atjobs),从中获取at命令提交的作业。在默认情况下,atd守护进程每隔60秒检查一次这个目录。如果其中有作业,那么atd守护进程就会查看此作业的运行时间。如果时间跟当前时间一致,就运行此作业。

接下来将介绍如何用at命令提交作业以及如何管理作业。

1.at命令的格式

at命令的基本格式非常简单:

at  [-f  filenametime

在默认情况下,at命令会将STDIN的输入放入队列。你可以用-f选项指定用于从中读取命令(脚本文件)的文件名。

time选项指定了你希望何时运行该作业。如果指定的时间已经过去,那么at命令会在第二天的同一时刻运行指定的作业。

指定时间的方式非常灵活。at命令能识别多种时间格式。

  • 标准的小时和分钟,比如10:15
  • AM/PM指示符,比如10:15 PM。
  • 特定的时间名称,比如now、noon、midnight或者teatime(4:00 p.m.)。

除了指定运行作业的时间,也可以通过不同的日期格式指定特定的日期。

  • 标准日期,比如MMDDYY、MM/DD/YY或DD.MM.YY。
  • 文本日期,比如Jul 4或Dec 25,加不加年份均可。
  • 时间增量。
    • Now + 25 minutes
    • 10:15 PM tomorrow
    • 10:15 + 7 days

提示        at命令可用的日期和时间格式有很多种,具体参见/usr/share/doc/at/timespec文件。

在使用at命令时,该作业会被提交至作业队列。作业队列保存着通过at命令提交的待处理作业。针对不同优先级,有52种作业队列。作业队列通常用小写字母a~z和大写字母A~Z来指代,A队列和a队列是两个不同的队列。

注意        在几年前,batch命令也能指定脚本的执行时间。这是个很独特的命令,因为它可以安排脚本在系统处于低负载时运行。现在,batch命令只不过是一个脚本而已(/usr/bin/batch) ,它会调用at命令将作业提交到b队列中。

作业队列的字母排序越高,此队列中的作业运行优先级就越低(谦让度更大) 。在默认情况下,at命令提交的作业会被放入a队列。如果想以较低的优先级运行作业,可以用-q选项指定其他的队列。如果相较于其他进程你希望你的作业尽可能少地占用CPU,可以将其放入z队列。

2.获取作业的输出

当在Linux系统中运行at命令时,显示器并不会关联到该作业。Linux系统反而会将提交该作业的用户email地址作为STDOUT和STDERR。任何送往STDOUT或STDERR的输出都会通过邮件系统传给该用户。

来看一个在CentOS发行版中使用at命令调度作业的例子:

$ cat tryat.sh
#!/bin/bash
# Trying out the at command
#
echo "This script ran at $(date +%B%d,%T)"
echo
echo "This script is using the $SHELL shell."
echo
sleep 5
echo "This is the script's end."
#
exit
$
$ at -f tryat.sh now
warning: commands will be executed using /bin/sh
job 3 at Fri Feb 7 16:23:00 2025
$

at命令会显示分配给作业的作业号以及为作业安排的运行时间。-f选项指明使用哪个脚本文件。now指示at命令立刻执行该脚本。

注意        无须在意at命令输出的警告消息,因为脚本的第一行是#!/bin/bash,该命令会由bash shell执行。

使用email作为at命令的输出极不方便。at命令通过sendmail应用程序发送email。如果系统中没有安装sendmail,那就无法获得任何输出。因此在使用at命令时,最好在脚本中对STDOUT和STDERR进行重定向,如下例所示:

$ cat tryatout.sh
#!/bin/bash
# Trying out the at command redirecting output
#
outfile=$HOME/scripts/tryat.out
#
echo "This script ran at $(date + %B%d,%T)" > $outfile
echo >> $outfile
echo "This script is using the $SHELL shell." >> $outfile
echo >> $outfile
sleep 5
echo "This is the script's end." >> $outfile
#
exit
$
$ at -M -f tryatout.sh now
warning: commands will be executed using /bin/sh
job 4 at Fri Feb 7 16:48:00 2025
$
$ cat $HOME/scripts/tryat.out
This scrit ran at Feb7,16:48:21This script is using the /bin/bash shell.This is the script's end.
$

 如果不想在at命令中使用email或者重定向,则最好加上-M选项,以禁止作业产生的输出信息。

3.列出等待的作业

atq命令可以查看系统中有哪些作业在等待:

$ at -M -f tryatout.sh teatime
warnign: commands will be executed using /bin/sh
job 5 at Sat Feb 8 16:00:00 2025
$
$ at -M -f tryatout.sh tomorrow
warning: commands will be executed using /bin/sh
jb 6 at Sat Feb 8 16:53:00 2025
$
$ at -M -f tryatout.sh 20:30
warning: commands will be executed using /bin/sh
job 7 at Fri Feb 7 20:30:00 2025
$
$ at -M -f tryatout.sh now+1hour
warning: commands will be executed using /bin/sh
job 8 at Fri Feb 7 17:54:00 2025
$
$ atq
1      Fri Feb 7 16:11:00 2025 a christine
5      Sat Feb 8 16:00:00 2025 a christine
6      Sat Feb 8 16:53:00 2025 a christine
7      Fri Feb 7 20:30:00 2025 a christine
8      Fri Feb 7 17:54:00 2025 a christine
$

作业列表中显示了作业号、系统运行该作业的日期和时间,以及该作业所在的作业队列。

4.删除作业

一旦知道了哪些作业正在作业队列中等待,就可以用atrm命令删除等待中的作业。指定要删除的作业号即可:

$ atq
1      Fri Feb 7 16:11:00 2025 a christine
5      Sat Feb 8 16:00:00 2025 a christine
6      Sat Feb 8 16:53:00 2025 a christine
7      Fri Feb 7 20:30:00 2025 a christine
8      Fri Feb 7 17:54:00 2025 a christine
$
$ atrm 5
$
$ atq
1      Fri Feb 7 16:11:00 2025 a christine
6      Sat Feb 8 16:53:00 2025 a christine
7      Fri Feb 7 20:30:00 2025 a christine
8      Fri Feb 7 17:54:00 2025 a christine
$

只能删除自己提交的作业,不能删除其他人的。

2.调度需要定期运行的脚本

使用at命令安排在未来的预设时间运行某个脚本固然不错,但如果需要脚本在每天、每周或每月的同一时间运行呢?这时候与其频繁使用at命令,不如利用Linux系统的另一个特性。

Linux系统使用cron程序调度需要定期执行的作业。cron在后台运行,并会检查一个特殊的表(cron时间表),从中获知已安排执行的作业。

1.cron时间表

cron时间表通过一种特别饿格式指定作业何时运行,其格式如下:

minutepasthour hourofday dayofmonth month dayofweek command

cron时间表允许使用特定值、取值范围(比如1~5)或者通配符(星号)来指定各个字段。如果想在每天的10:15运行一个命令,可以使用如下cron时间表字段:

15  10  *  *  *  command

dayofmonth、month以及dayofweek字段中的通配符表明,cron会在每天10:15执行该命令。要指定一条在每周一的下午4:15(4:15 p.m.)执行的命令,可以使用军事时间(1:00 p.m.是13:00,2:00 p.m.是14:00,3:00 p.m.是15:00,以此类推),如下所示:

15  16  *  *  1  command

可以使用三字符的文本值(mon、tue、web、thu、fri、sat、sun)或数值(0或7代表周日,6代表周六)来指定dayofweek字段。

这里还有另一个例子。要想在每月第一天的中午12点执行命令,可以使用下列字段:

00  12  1  *  *  command

dayofmonth字段指定的是月份中的日期值(1~31)。

提示        聪明的你可能会思考,如何设置才能让命令在每月的最后一天执行,因为无法设置一个dayofmonth值,涵盖所有月份的最后一天。常用的解决方法是加一个if-then语句,在其中使用date命令检查明天的日期是不是某个月份的第一天(01):

00 12 28-31 * * if [ "$(date +%d -d tomorrow)" = 01 ] ; then command ; fi

这行脚本会在每天中午12点检查当天是不是当月的最后一天(28~31),如果是,就由cron执行command

另一种方法是将command替换成一个控制脚本(controlling script),在可能是每月最后一天的时候运行。控制脚本包含if-then语句,用于检查第二天是否为某个月的第一天。如果是,则由控制脚本发出命令,执行必须在当月最后一天执行的内容。

命令列表必须指定要运行的命令或脚本的完整路径。你可以像在命令行中那样,添加所需的任何选项和重定向符:

15  10  *  *  *  /home/christine/backup.sh > backup.out

cron程序会以提交作业的用户身份运行该脚本,因此你必须有访问该脚本(或命令) 以及输出文件的合理权限。

2.构建cron时间表

每个用户(包括root用户)都可以使用自己的cron时间表运行已安排好的任务。Linux提供了crontab命令来处理cron时间表。要列出已有的cron时间表,可以用-l选项:

$ crontab -l
no crontab for christine
$

在默认情况下,用户的cron时间表文件并不存在。可以使用-e选项向cron时间表添加字段。在添加字段时,crontab命令会启动一个文本编辑器,使用已有的cron时间表作为文件内容(如果时间表不存在,就是一个空文件)。

3.浏览cron目录

如果创建的脚本对于执行时间的精确性要求不高,则用预配置的cron脚本目录会更方便。预配置的基础目录共有4个:hourly、daily、monthly和weekly。

$ ls /etc/cron.*ly
/etc/cron.daily:
0anacron  apt-compat    cracklib-runtime  logrotate  [...]
apport    bsdmainutils  dpkg              man-db     [...]/etc/cron.hourly:/etc/cron.monthly:
0anacron/etc/cron.weekly:
0anacron  man-db  update-notifier-common
$

如果你的脚本需要每天运行一次,那么将脚本复制到daily目录,cron就会每天运行它。

4.anacron程序

cron程序唯一的问题是它假定Linux系统是7 x 24小时运行的。除非你的Linux运行在服务器环境,否则这种假设未必成立。

如果某个作业在cron时间表中设置的运行时间已到,但这时候Linux系统处于关闭状态,那么该作业就不会运行。当再次启动系统时,cron程序不会再去运行那些错过的作业。为了解决这个问题,许多Linux发行版提供了anacron程序。

如果anacron判断出某个作业错过了设置的运行时间,它会尽快运行该作业。这意味着如果Linux系统关闭了几天,等到再次启动时,原计划在关机期间运行的作业会自动运行。有了anacron,就能确保作业一定能运行,这正是通常使用anacron代替cron调度作业的原因。

anacron程序只处理位于cron目录的程序,比如/etc/cron.monthly。它通过时间戳来判断作业是否在正确的计划间隔内运行了。每个cron目录都有一个时间戳文件,该文件位于/var/spool/anacron:

$ ls /var/spool/anacron
cron.daily cron.monthly cron.daily
$
$ sudo cat /var/spool/anacron/cron.daily
[sudo] password for christine:
20250208
$

anacron程序使用自己的时间表(通常位于/etc/anacrontab)来检查作业目录:

$ cat /etc/anacrontab
# /etc/anacrontab: configuration file for anacron# See anacron(8) and anacrontab(5) for details.SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
HOME=/root
LOGNAME=root# These replace cron's entries
1      5      cron.daily      run-parts --report /etc/cron.daily
7      10     cron.weekly     run-parts --report /etc/cron.weekly
@monthly 15   cron.monthly    run-parts --report /etc/cron.monthly
$

anacron时间表的基本格式和cron时间表略有不同:

period  delay  identifier  command

period字段定义了作业的运行频率(以天为单位)。anacron程序用该字段检查作业的时间戳文件。delay字段指定了在系统启动后,anacron程序需要等待多少分钟再开始运行错过的脚本。

注意        anacron不会运行位于/etc/cron.hourly目录的脚本。这是因为anacron并不处理执行时间需求少于一天的脚本。

identifier字段是一个独特的非空字符串,比如cron.weekly。它唯一的作用是标识出现在日志消息和错误email中的作业。command字段包含了run-parts程序和一个cron脚本目录名。run-parts程序负责运行指定目录中的所有脚本。

at、cron和anacron在调度作业运行方面各占有一席之地。然而,你可能希望在用户启动新的bash shell而不是特定时刻执行某个脚本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/15522.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2025web寒假作业二

一、整体功能概述 该代码构建了一个简单的后台管理系统界面,主要包含左侧导航栏和右侧内容区域。左侧导航栏有 logo、管理员头像、导航菜单和安全退出按钮;右侧内容区域包括页头、用户信息管理内容(含搜索框和用户数据表格)以及页…

服务器ip被反垃圾列为黑名单

查询 BarracudaCentral.org - Technical Insight for Security Pros https://multirbl.valli.org/lookup/ 大概写:我不知道这个IP在我使用之前已被列入Barracuda信誉阻止列表(BRBL)。我不知道它之前列出的原因,但服务器现在有了…

2025影视泛目录站群程序设计_源码二次开发新版本无缓存刷新不变实现原理

1. 引言 本设站群程序计书旨在详细阐述苹果CMS泛目录的创新设计与实现,介绍无缓存刷新技术、数据统一化、局部URL控制及性能优化等核心功能,以提升网站访问速度和用户体验。 2. 技术概述 2.1 无缓存刷新技术 功能特点: 内容不变性&#x…

激活函数 05 ——Swish

Swish背景 发展阶段典型函数主要特性局限性早期阶段Sigmoid/Tanh平滑可导,输出有界梯度消失问题现代阶段ReLU计算高效,缓解梯度消失神经元死亡现象改进阶段LeakyReLU改善负区间响应参数敏感性新星阶段Swish/GELU自适应非线性计算复杂度略高 Swish激活函…

Tria Technologies RFSoC 平台 - 入门指南

Tria Technologies RFSoC 平台 - 入门指南 适用于 RFSoC Gen-3 的宽带毫米波无线电开发平台 该平台将 Otava 和 Avnet 联合开发的 Otava DTRX2 双收发器毫米波无线电卡与 AMD Xilinx Zynq UltraScale ™ RFSoC ZCU208 评估套件相结合。 5G 毫米波相控阵天线模块开发平台 …

Win11下搭建Kafka环境

目录 一、环境准备 二、安装JDK 1、下载JDK 2、配置环境变量 3、验证 三、安装zookeeper 1、下载Zookeeper安装包 2、配置环境变量 3、修改配置文件zoo.cfg 4、启动Zookeeper服务 4.1 启动Zookeeper客户端验证 4.2 启动客户端 四、安装Kafka 1、下载Kafka安装包…

白嫖RTX 4090?Stable Diffusion:如何给线稿人物快速上色?

大家都知道,在设计的初期,我们通常会先绘制草图,然后再进行上色处理,最终才开始进行最终的设计工作。在这个上色的过程中,配色是至关重要的一环。这不仅方便了内部同事的评审,也让产品方和客户可以直观地了…

从大规模恶意攻击 DeepSeek 事件看 AI 创新隐忧:安全可观测体系建设刻不容缓

作者:羿莉(萧羿) 全球出圈的中国大模型 DeepSeek 作为一款革命性的大型语言模型,以其卓越的自然语言处理能力和创新性成本控制引领行业前沿。该模型不仅在性能上媲美 OpenAI-o1,而且在推理模型的成本优化上实现了突破…

AMD 8845HS 780M核显部署本地deepseek大模型的性能

测试了一下笔记本电脑AMD 8845HS的780M核显是否能本地部署deepseek大模型。 测试软件环境:LM Studio 0.3.9 、Windows 11 24H2 硬件:荣耀X16笔记本 CPU:AMD 8845HS 显卡:780M核显,显存为共享内存自动分配模式&…

利用二分法进行 SQL 盲注

什么是sql注入? SQL 注入(SQL Injection)是一种常见的 Web 安全漏洞,攻击者可以通过构造恶意 SQL 语句来访问数据库中的敏感信息。在某些情况下,服务器不会直接返回查询结果,而是通过布尔值(Tr…

《深度学习》——pytorch框架及项目

文章目录 pytorch特点基本概念 项目项目实现导入所需库下载训练数据和测试数据对训练和测试样本进行分批次展示手写图片判断pytorch是否支持GPU定义神经网络模型定义训练函数定义测试函数创建交叉熵损失函数和优化器通过多轮训练降低损失值得到最终结果注意 pytorch PyTorch 是…

【批量获取图片信息】批量获取图片尺寸、海拔、分辨率、GPS经纬度、面积、位深度、等图片属性里的详细信息,提取出来后导出表格,基于WPF的详细解决方案

摄影工作室通常会有大量的图片素材,在进行图片整理和分类时,需要知道每张图片的尺寸、分辨率、GPS 经纬度(如果拍摄时记录了)等信息,以便更好地管理图片资源,比如根据图片尺寸和分辨率决定哪些图片适合用于…

windows生成SSL的PFX格式证书

生成crt证书: 安装openssl winget install -e --id FireDaemon.OpenSSL 生成cert openssl req -x509 -newkey rsa:2048 -keyout private.key -out certificate.crt -days 365 -nodes -subj "/CN=localhost" 转换pfx openssl pkcs12 -export -out certificate.pfx…

UnityShader学习笔记——高级纹理

——内容源自唐老狮的shader课程 目录 1.立方体纹理 1.1.概念 1.2.用处 1.3.如何采样 1.4.优缺点 2.天空盒 2.1.概念 2.2.优点 2.3.设置 3.动态生成立方体纹理 3.1.原因 3.2.实现 3.3.代码运行中生成 4.反射 4.1.原理 4.2.补充知识 5.折射 5.1.原理 5.2.菲涅…

IBM服务器刀箱Blade安装Hyper-V Server 2019 操作系统

案例:刀箱某一blade,例如 blade 5 安装 Hyper-V Server 2019 操作系统(安装进硬盘) 刀箱USB插入安装系统U盘,登录192.168... IBM BlandeCenter Restart Blande 5,如果Restart 没反应,那就 Power Off Blade 然后再 Power On 重启后进入BIOS界面设置usb存储为开机启动项 …

C++20新特性

作者:billy 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 前言 C20 是 C 标准中的一个重要版本,引入了许多新特性和改进,包括模块(Modules)、协程…

WPS如何接入DeepSeek(通过JS宏调用)

WPS如何接入DeepSeek 一、文本扩写二、校对三、翻译 本文介绍如何通过 WPS JS宏调用 DeepSeek 大模型,实现自动化文本扩写、校对和翻译等功能。 一、文本扩写 1、随便打开一个word文档,点击工具栏“工具”。 2、点击“开发工具”。 3、点击“查看代码”…

【SQL server】关于SQL server彻底的卸载删除。

1.未彻底卸载删除SQL Server会出现的问题 如果没有彻底删除之前的SQL server,就可能会出现这个 当要安装新的实例的时候因为之前安装过sql server没有删除干净而导致下图问题,说实例名已经存在。 2.首先要先关闭服务 “开始R”可以快速进入运行&#…

对话框补充以及事件处理机制 (2025.2.10)

作业 1> 将鼠标事件和键盘事件相关代码重新实现一遍 2> 将文本编辑器功能完善 主函数main.cpp #include "widget.h"#include <QApplication>int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 头…

企业级Mysql实战

Mysql企业级sql编写实战 1 一对多&#xff0c;列表展示最新记录字段1.1 场景1.2 需求1.3 实现1.3.1 表及数据准备1.3.2 Sql编写 2 区间统计&#xff08;if/case when&#xff09;2.1 场景2.2 需求2.3 实现2.2.1 表及数据准备2.3.2 sql编写 3 多类别分组统计&#xff08;竖表转横…