本章介绍如何使用 Vim 编辑器来编写和修改文档,然后通过逐步配置主机名称、系统网卡以及软件仓库等文件,加深 Vim 编辑器中诸多命令、快捷键与模式的理解;能够在 Shell 脚本中以多种方式接收用户输入的信息,能够对输入值进行文件、数字、字符串的判断比较。在熟练使用“与、或、非”三种逻辑操作符的基础上,还要充分学习 if、for、while、case 条件测试语句。
最后通过实战的方式演示了使用 at 命令与 crond 计划任务服务来分别实现一次性的系统任务设置和长期性的系统任务设置,在分钟、小时、日期、月份、年份的基础上实现工作的自动化,从而让日常的工作更加高效。
4.1 Vim 文本编辑器
Vim 的发布最早可以追溯到 1991 年,英文全称为 Vi Improved。它也是 Vi 编辑器的提升版本,其中最大的改进当属添加了代码着色功能,在某些编程场景下还能自动修正错误代码。 记得尤其深刻:“在 Linux 系统中一切都是文件,而配置一个服务就是在修改其配置文件的参数。”而且在日常工作中也肯定免不了要编写文档,这些工作都是通过文本编辑器来完成的;它默认会安装在当前所有的 Linux 操作系统上,是一款超棒的文本编辑器。
Vim 编辑器中设置了 3 种模式—命令模式、末行模式和编辑模式,每种模式分别又支持多种不同的命令快捷键,这大大提高了工作效率,而且用户在习惯之后也会觉得相当顺手。要想高效地操作文本,就必须先搞清这 3 种模式的操作区别以及模式之间的切换方法(见图 4-1)。
➢命令模式:控制光标移动,可对文本进行复制、粘贴、删除和查找等工作。
➢输入模式:正常的文本录入。
➢末行模式:保存或退出文档,以及设置编辑环境。
在每次运行 Vim 编辑器时默认是命令模式,此时需要先切换到输入模式后再进行文档编写工作。而每次在编写完文档后需要先返回命令模式,然后再进入末行模式,执行文档的保存或退出操作。在 Vim 中,无法直接从输入模式切换到末行模式。Vim 编辑器中内置的命令有成百上千种用法,总结了在命令模式中最常用的一些命令如图。
末行模式主要用于保存或退出文件,以及设置 Vim 编辑器的工作环境,还可以让用户执行外部的 Linux 命令或跳转到所编写文档的特定行数。要想切换到末行模式,在命令模式中输入一个冒号就可以了。末行模式中常用的命令如表。
4.1.1 编写简单文档
编写脚本文档的第 1 步就是给文档取个名字,这里将其命名为 test0.txt;如果存在该文档则是打开它。如果不存在则是创建一个临时的输入文件如图。
回车键打开 test0.txt 文档后,默认进入的是 Vim 编辑器的命令模式。此时只能执行该模式下的命令,而不能随意输入文本内容。我们需要切换到输入模式才可以编写文档;在图 4-1 中提到可以分别使用 a、i、o 这 3 个键从命令模式切换到输入模式。其中a 键与 i 键分别是在光标后面一位和光标当前位置切换到输入模式,而 o 键则是在光标的下面再创建一个空行。
进入输入模式后,可以随意输入文本内容,Vim 编辑器不会把您输入的文本内容当作命令而执行如图
在编写完之后,要想保存并退出,必须先敲击键盘的 Esc 键从输入模式返回命令模式, 然后再输入“:wq!”切换到末行模式才能完成保存退出操作。
请注意左下角默认命令模式时是空白,按a键进入输入模式后会显示-- INSERT--字符,按ESC回命令模式再按(:号)进入末行模式会有( : 号)字符,此时才可以输入“:wq!”命令强制保存并退出文档。接着可以用 cat 命令查看保存后的文档如图。
如果想要在原有文本内容的下面追加内容,那么就继续vim该文件在命令模式中敲击 o 键进入输入模式,且光标会自动跳到第二行如图。
再次编辑好文档后如果不保存输入:q直接退出,这时系统会检测到文件有修改而拒绝(左下角红色提示)退出,只能:q!强制退出才能结束本次输入操作如图。
再次查看文本的内容,果然追加输入的内容并没有被保存下来,如图。
经过上面的文本测试,现在是否感觉还行呢,接下来将会由浅入深地继续安排 3 个小任务逐个完成实验。
4.1.2 配置主机名称
为了便于在局域网中查找某台特定的主机,或者对主机进行区分,除了要有 IP 地址外还要为主机配置一个主机名,主机之间可以通过这个类似于域名的名称来相互访问。在 Linux 系统中,主机名大多保存在/etc/hostname 文件中,接下来将/etc/hostname 配置文件的内容修改为“linuxprobe.com”,步骤如下。
第1步:使用Vim编辑器修改/etc/hostname主机名称文件。
第2步:把原始主机名称删除改为RHEL8probe”。修改主机名称文件后,记得在末行模式下执行“:wq!”命令才能保存并退出文档。
第3步:保存并退出文档,然后使用hostname命令检查是否修改成功。
hostname 命令用于查看当前的主机名称,但有时主机名称的改变不会立即同步到系统中,所以如果发现修改完成后还显示原来的主机名称,可重启虚拟机后再查看。
4.1.3 配置网卡信息
网卡 IP 地址配置的是否正确是两台服务器是否可以相互通信的前提,因此配置网络服务的工作其实就是在编辑网卡配置文件。这个小任务不仅可以练习使用 Vim 编辑器,而且也为后面学习 Linux 中的各种服务配置打下了坚实的基础。
在 RHEL 5、RHEL 6 中,网卡配置文件的前缀为 eth,第 1 块网卡为eth0,第 2 块网卡为 eth1以此类推。在 RHEL 7 中网卡配置文件的前缀则以 ifcfg 开始,再加上网卡名称共同组成了网卡配置文件的名字,例如 ifcfg-eno16777736。而在 RHEL 8 中网卡配置文件的前缀依然为 ifcfg,区别是网卡名称改成了类似于 ens160 的样子,好在网卡参数没有其他大的区别。
现在有一个名称为 ifcfg-ens160 的网卡设备,将其配置为开机自启动,并且 IP 地址、子网、网关等信息由人工指定,其步骤如下所示。
第1步:首先切换到/etc/sysconfig/network-scripts目录中(存放着网卡的配置文件)。
第2步:使用Vim编辑器修改网卡文件ifcfg-ens160,逐项写入下面的配置参数并保存退出。
设备类型:TYPE=Ethernet
地址分配模式:BOOTPROTO=static
网卡名称:NAME=ens160
是否启动:ONBOOT=yes
IP地址:IPADDR=192.168.10.10
子网掩码:NETMASK=255.255.255.0
网关地址:GATEWAY=192.168.10.1
DNS地址:DNS1=192.168.10.1
第3步:重启网络服务并测试网络是否连通。
由于每台设备的硬件及架构有不一样,可以使用ifconfig命令确认本机网卡的默认名称;进入到网卡配置文件所在的目录,然后编辑网卡配置文件写入第2步的信息保存并退出。
执行重启网卡设备的命令:nmcli connection reload [网卡名],然后通过 ping 命令测试网络能否连通。由于在 Linux 系统中 ping 命令不会自动终止,可以手动按下 Ctrl+C 组合键来强行结束进程。
4.1.4 配置软件仓库
软件仓库是一种能进一步简化 RPM 管理软件的难度以及自动分析所需软件包及其依赖关系的技术。可以把 Yum 或 DNF 想象成是一个硕大的软件仓库,里面保存有几乎所有常用的工具,而且只需要输出所需的软件包名称,系统就会自动匹配安装。
要使用软件仓库就要先把它搭建起来,Yum 与 DNF 软件仓库的配置文件是通用的,虽然命令不同但都可以正常调用。建议在 RHEL 8 中使用 dnf 作为软件的安装命令,因为它具备更高的效率,而且支持多线程同时安装软件。搭建并配置软件仓库的大致步骤如下。
第1步:进入/etc/yum.repos.d/目录中(因为该目录存放着软件仓库的配置文件)。
第2步:使用Vim编辑器创建一个名为rhel8.repo的新配置文件(文件名称可随意,但后缀必须为.repo),逐项写入下面的配置参数保存并退出。
➢仓库名称:具有唯一性的标识名称,不应与其他软件仓库发生冲突。
➢描述信息(name):可以是一些介绍性的词,易于识别软件仓库的用处。
➢仓库位置(baseurl):软件包的获取方式,可以使用FTP或HTTP下载,也可以是本地的文件(需要在后面添加file参数)。
➢是否启用(enabled):设置此源是否可用;1为可用,0为禁用。
➢是否校验(gpgcheck):设置此源是否校验文件;1为校验,0为不校验。
➢公钥位置(gpgkey):若上面的参数开启了校验功能,则此处为公钥文件位置。若没有开启,则省略不写。
第3步:按配置参数中所填写的仓库位置挂载光盘,并把光盘挂载信息写入/etc/fstab文件中。
第4步:使用“dnf install httpd -y”命令检查软件仓库是否已经可用。
首先进入/etc/yum.repos.d目录,用vim新建rhel8.repo文件写入第2步的配置信息保存并退出。
创建挂载点后进行挂载操作,并修改/etc/fstab文件实现开机自动挂载。
尝试使用软件仓库的dnf命令来安装Web服务,软件包名称为httpd,安装后尾行出现“Complete!”则代表完成,配置正确;也可以使用yum install httpd命令来安装。
4.2 编写 Shell 脚本
可以将 Shell 终端解释器当作人与计算机硬件之间的“翻译官”,它作为用户与 Linux 系统内部的通信媒介,除了能够支持各种变量与参数外,还提供了如循环、分支等高级编程语言才有的控制结构特性。要想正确使用 Shell 中的这些功能特性,准确编写命令尤为重要。Shell 脚本命令的工作方式有下面两种。
➢交互式(Interactive):用户每输入一条命令就立即执行。
➢批处理(Batch):由用户事先编写好一个完整的Shell脚本,Shell会一次性执行脚本中诸多的命令。
在 Shell 脚本中不仅会用到很多 Linux 命令以及正则表达式、管道符、数据流重定向等语法规则,还会把内部功能模块化后通过逻辑语句进行处理,最终形成日常所见的 Shell 脚本。通过查看 SHELL 变量可以发现,当前系统已经默认使用 Bash 作为命令行终端解释器了。
4.2.1 编写简单的脚本
看完上文中 Shell 脚本的描述后,有没有觉得很复杂?上文指的是一个高级 Shell 脚本的编写原则,其实使用 Vim 编辑器把 Linux 命令按照顺序依次写入到一个文件中,就是一个简单的脚本了。例如想查看当前所在工作路径并列出当前目录下所有的文件及属性信息,实现这个功能的脚本类似于下面这样。
Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将.sh 后缀加上,以表示是一个脚本文件。在上面的这个 task.sh 脚本中实际上出现了 3 种不同的元素:
第一行的脚本声明(#!)用来告诉系统使用哪种 Shell 解释器来执行该脚本;第二行的注释信息(#)是对脚本功能和某些命令的介绍信息,使得自己或他人在日后看到这个脚本内容时,可以快速知道该脚本的作用或一些警告信息;第三、四行的可执行语句也就是我们平时执行的 Linux 命令了。
下面来执行一下看看效果。
除了上面用 Bash 解释器命令直接运行 Shell 脚本文件外,第二种运行脚本程序的方法是通过输入完整路径的方式来执行。但默认会因为权限不足而提示报错信息,此时只需要为脚本文件增加执行权限即可(详见下一篇)
4.2.2 接收用户的参数
像上面这样的脚本程序只能执行一些预先定义好的功能,比较固定。为了让 Shell 脚本程序更好地满足用户的一些实时需求,以便灵活完成工作,必须要让脚本程序能够像之前执行命令时那样,接收用户输入的参数。 比如当用户执行某一个命令时,加或不加参数的输出结果是不同的。
在Linux 系统中的 Shell 脚本语言已经内设了用于接收参数的变量,变量之间使用空格间隔。如下:
➢ $0 对应的是当前 Shell 脚本程序的名称;
➢ $#对应的是总共有几个参数;
➢ $*对应的是所有位置的参数值;
➢ $?对应的是显示上一次命令的执行返回值;
➢ $1、$2、$3……则分别对应着第 N 个位置的参数值。
下面来编写一个脚本程序示例,通过引用上面的变量参数来看一下实际效果,可以看到输入的参数与test.sh脚本相互产生的结果。
4.2.3 判断用户的参数
了解 Shell 脚本语法变量和接收用户输入的信息之后,还可以进一步处理接收到的用户参数。在执行 mkdir 命令时会判断用户输入的信息,即判断用户指定的文件夹名称是否已经存在,如果存在则提示报错;反之则会创建。Shell 脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字 0,否则便返回非零值。注意!条件表达式 中括号两边均应有一个空格。
按照测试对象来划分,条件测试语句可以分为 4 种:
➢ 文件测试语句;
➢ 逻辑测试语句;
➢ 整数值比较语句;
➢ 字符串比较语句。
文件测试即使用指定条件来判断文件是否存在或权限是否满足等情况的运算符,具体的参数如图 。
下面使用文件测试语句来判断/etc/fstab 是否为一个目录类型的文件,然后通过 Shell 解释器的内设$?变量显示上一条命令执行后的返回值。如果返回值为 0,则目录存在;如果返回值为非零的值,则意味着它不是目录,或这个目录不存在;再判断/etc/fstab 是否为一般文件,如果返回值为 0,则代表文件存在,且为一般文件。注意!条件表达式 中括号两边均应有一个空格。
判断与查询也可以一条命令完成。 逻辑语句用于对测试结果进行逻辑分析,根据测试结果可实现不同的效果如下。
➢ &&是逻辑“与”,只有当前面的语句执行成功的时候才会执行后面的语句。
➢ ||是逻辑“或”,只有当前面的语句执行失败的时候才会执行后面的语句。
➢ !是逻辑“非”,代表对逻辑测试结果取反值;之前若为正确则变成错误,若为错误则变成正确。
下面用 && 来判断/dev/sr0 文件是否存在,若存在则输出 Exist 字样。
用 || 来结合系统环境变量 $USER 来判断当前登录的用户是否为非管理员身份,切换用户后再次验证结果不是。
再用 !判断当前用户是否为一个非管理员的用户。由于语句同时加上了 || 结果因为两次否定而变成正确,因此会正常地输出预设信息;叹号应该放到判断语句的前面,代表对整个测试语句进行取反值操作,而不应该写成 “$USER != root”,因为“!=”目测为非等于符号(≠),尽管执行效果一样,但缺少了逻辑关系。
最后做个结合示例,先判断当前登录用户的 USER 变量名称是否等于 root,然后用逻辑“非”运算符进行取反操作,效果就变成了当前登录的用户为非管理员用户。然后若条件成立,则会根据逻辑“与”运算符输出 user 字样;若条件不满足,则会通过逻辑“或”运算符输出 root 字样;而只有在前面的 && 不成立时才会执行后面的 || 符。
整数比较运算符仅是对数字的操作,不能将数字与字符串、文件等内容一起操作,而且不能使用日常生活中的等号、大于号、小于号等来判断。因为等号与赋值命令符冲突,大于号和小于号分别与输出重定向命令符和输入重定向命令符冲突。因此便有了使用规范的整数比较运算符来进行操作。可用的整数比较运算符如图。
下面测试一下 18 是否大于 18 以及 18 是否等于 18(通过输出的返回值内容来判断)。
字符串比较语句用于判断测试字符串是否为空值,或两个字符串是否相同。它经常用来判断某个变量是否未被定义(即内容为空值),理解起来也比较简单。字符串比较中常见的运算符如图。
接下来通过判断 String 变量是否为空值,进而判断是否定义了这个变量; 再次尝试引入逻辑运算符来试一下。当用于保存当前语系的环境变量值 LANG 不是英语(en.US)时,则会满足逻辑测试条件并输出“Not en.US”(非英语)的字样。
4.3 流程控制语句
尽管可以通过使用 Linux 命令、管道符、重定向以及条件测试语句来编写最基本的 Shell 脚本,但是这种脚本不太适用于生产环境;就是不能满足实际工作多变的应用需求。通常脚本都是从上到下一股脑儿地执行,效率是很高,但一旦某条命令执行失败了,则后面的功能全都会受到影响。
接下来通过 if、for、while、case 这 4 种流程控制语句来学习编写难度更大、功能更强的 Shell 脚本。
4.3.1 if 条件测试语句
if 条件测试语句可以让脚本根据实际情况自动执行相应的命令。从技术角度来讲,if 语句分为单分支结构、双分支结构、多分支结构;其复杂度随着灵活度一起逐级上升。if 条件语句的单分支结构由 if、then、fi 关键词组成,而且只在条件成立后才执行预设的命令,相当于口语的“如果……那么……”。单分支的 if 语句属于最简单的一种条件判断结构,语法格式如图。
下面使用单分支的 if 条件语句来判断/media/sr0 目录是否存在,若不存在就创建这个目录,反之则结束条件判断和整个 Shell 脚本的执行。在正常情况下,顺利执行完脚本文件后没有任何输出信息,但是可以使用 ls 命令验证 /media/sr0 目录是否已经成功创建。
if 条件语句的双分支结构由 if、then、else、fi 关键词组成,它进行一次条件匹配判断,如果与条件匹配,则去执行相应的预设命令;反之则去执行不匹配时的预设命令,相当于口语的“如果……那么……或者……那么……”。if 条件语句的双分支结构也是一种很简单的判断结构,语法格式如图。
下面使用双分支的 if 条件语句来验证某台主机是否在线,然后根据返回值的结果,要么显示主机在线信息,要么显示主机不在线信息。这里的脚本主要使用 ping 命令来测试与对方主机的网络连通性,而 Linux 系统中的 ping 命令不像 Windows 一样尝试 4 次就结束,因此为了避免等待时间过长,需要通过-c 参数来规定尝试的次数,并使用-i 参数定义每个数据包的发送间隔,以及使用-W 参数定义等待超时时间。
/dev/null 是一个被称作 Linux 黑洞的文件,把输出信息重定向到这个文件等同于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁。
前面提到bash解释器内置的$?变量作用是显示上一次命令的执行返回值。若前面的那条语句成功执行,则$?变量会显示数字 0,反之则显示一个非零的数字(可能为 1,也可能为 2,取决于系统版本)。因此可以使用整数比较运算符-eq来判断$?变量是否为 0,从而获知那条语句的最终判断情况。来验证一下脚本的执行结果。
if 条件语句的多分支结构由 if、then、else、elif、fi 关键词组成,它进行多次条件匹配判断,这多次判断中的任何一项在匹配成功后都会执行相应的预设命令,相当于口语的“如果……那么……如果……那么……”。if 条件语句的多分支结构是工作中最常使用的一种条件判断结构,尽管相对复杂但是更加灵活,语法格式如图 4-20 所示。
下面使用多分支的 if 条件语句来判断用户输入的分数在哪个成绩区间,然后输出如Excellent、Pass、Fail 等提示信息。在 Linux 系统中,read 是用来读取用户输入信息的命令,能够把接收到的用户输入信息赋值给后面的指定变量,-p 参数用于向用户显示一些提示信息。
只有当用户输入的分数大于等于 85 分且小于等于 100 分时,才输出 Excellent 字样;若分数不满足该条件(即匹配不成功),则继续判断分数是否大于等于 70分且小于等于 84 分,如果是,则输出 Pass 字样;若两次都落空(即两次的匹配操作都失败了),则输出 Fail 字样。
为什么输入的分数为 101 时,依然显示 Fail 呢?原因很简单—没有成功匹配脚本中的两个条件判断语句,因此执行了最终的兜底策略。说明这个脚本还不是很完美,若能在输入大于 100 或小于 0 的分数时,给予 Error 报错字更好。
4.3.2 for 条件循环语句
for 循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理。当要处理的数据有范围时,使用 for 循环语句就再适合不过了。for 循环语句的语法格式如图。
下面使用 for 循环语句从列表文件中读取多个用户名,然后为其逐一创建用户账户并设置密码。首先创建用户名称的列表文件 users.txt,每个用户名称单独一行。
再编写 Shell 脚本 addusers.sh。在脚本中使用 read 命令读取用户输入的密码值,然后赋值给 PASSWD 变量,并通过-p 参数向用户显示一段提示信息,告诉用户正在输入的内容即将作为账户密码。在执行该脚本后,会自动使用从列表文件 users.txt 中获取到所有的用户名称,然后逐一使用“id 用户名”命令查看用户的信息,并使用$?判断这条命令是否执行成功,也就是判断该用户是否已经存在。
接着执行批量创建用户的 Shell 脚本 addusers.sh,在输入为账户设定的密码后将由脚本自动检查并创建这些账户。由于已经将多余的信息通过输出重定向符转移到了/dev/null 黑洞文件中,因此在正常情况下屏幕窗口除了“用户账户创建成功”(Create success)的提示后不会有其他内容。
在 Linux 系统中,/etc/passwd 是用来保存用户账户信息的文件。如果想确认这个脚本是否成功创建了users.txt用户账户,可以用查看命令验证。
在上面内容双分支 if 条件语句时,用过测试主机是否在线的脚本,现在配合 for 循环语句尝试让脚本从文本中自动读取主机列表,然后自动逐个测试这些主机是否在线。 先创建一个主机列表文件 ips.txt。
然后将前面的双分支 if 条件语句与 for 循环语句相结合,让脚本从主机列表文件 ips.txt 中自动读取 IP 地址(用来表示主机)并将其赋值给 HLIST 变量,从而通过判断 ping 命令执行后的返回值来逐个测试主机是否在线。脚本中出现的“$(命令)”是类似于上一篇转义字符中反引号`命令`的 Shell 操作符,效果同样是执行括号或双引号括起来的字符串的命令。
Shell 脚本中的代码缩进格式会根据不同的语句而改变。这是由 Vim 编辑器自动完成的,用户无须进行额外操作。如果是 RHEL 7 以前的版本,则没有这个自动缩进功能,不过功能不受影响只是会影响阅读体验。
4.3.3 while 条件循环语句
while 条件循环语句是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前并不确定最终执行的次数,完全不同于 for 循环语句中有目标、有范围的使用场景。 while 循环语句通过判断条件测试的真假来决定是否继续执行命令,若条件为真就继续执行,为假就结束循环。while 语句的语法格式如图。
下面结合使用多分支的 if 条件测试语句与 while 条件循环语句,编写一个用来猜测数值大小的脚本 Guess.sh。该脚本使用$RANDOM 变量来调取出一个随机的数值(范围为 0~32767),然后将这个随机数对 1000 进行取余操作,并使用 expr 命令取得其结果,再用这个数值与用户通过 read 命令输入的数值进行比较判断。这个判断语句分为 3 种情况,分别是判断用户输入的数值是等于、大于还是小于使用 expr 命令取得的数值。
现在这些内容不是重点,要关注的是 while 条件循环语句中的条件测试始终为 true,因此判断语句会无限执行下去,直到用户输入的数值等于 expr 命令取得的数值后,才运行 exit 0 命令,终止脚本的执行。
在这个 Guess.sh 脚本中添加了一些交互式的信息,从而使得用户与系统的互动性得以增强。而且每当循环到 let TIMES++命令时都会让 TIMES 变量内的数值加 1,用来统计循环总计执行了多少次。这可以让用户得知在总共猜测了多少次之后,才猜对价格。
当条件为 true(真)的时候,while 语句会一直循环下去,只有碰到 exit 才会结束。
4.3.4 case 条件测试语句
case 条件测试语句和 switch(一种c语言语句) 的功能非常相似!case 语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令。case 语句的语法结构如图。
在 Guess.sh 脚本中有个弱点—只能接受数字!尝试输入一 个字母会发现脚本立即就会崩溃。原因是字母无法与数字进行大小比较,例如,“a 是否大于等于 3”这样的命题是完全错误的。必须有一定的措施来判断用户输入的内容,当用户输入的内容不是数字时,脚本能予以提示免于崩溃。
通过在脚本中组合使用 case 条件测试语句和通配符(上一篇内容),完全可以满足这里的需求。接下来编写脚本 keys.sh,提示用户输入一个字符并将其赋值给变量 KEY,然后根据变量 KEY 的值向用户显示其值是字母、数字还是其他字符。
4.4 计划任务服务程序
尽管我们现在已经有了功能强大的脚本程序来执行一些批处理工作,但是,如果仍然需要在每天凌晨两点敲击键盘回车键来执行这个脚本程序,就太痛苦了。接下来介绍如何设置服务器的计划任务服务,把周期性、规律性的工作交给系统自动完成;计划任务分为一次性计划任务与长期性计划任务,可以按照如下方式理解。
➢ 一次性计划任务:今晚23:30重启网站服务。
➢ 长期性计划任务:每周一的凌晨3:25把/home/wwwroot目录打包备份为backup.tar.gz。
一次性计划任务只执行一次,一般用于临时的工作需求。可以用 at 命令实现这种功能,只需要写成“at 时间”的形式就行。如果想要查看已设置好但还未执行的一次性计划任务,可以使用 at -l 命令;要想将其删除,可以使用“atrm 任务序号”。at 命令中的参数及其作用如图。
在使用 at 命令来设置一次性计划任务时,默认采用的是交互式方法。例如使用下述命令将系统设置为在今晚 23:59 自动重启网站服务,完成时同时按下<Ctrl>+<d>组合键来结束编写计划任务。
可以把前面学习的管道符(任意门)放到两条命令之间,让 at 命令接收前面 echo 命令的输出信息,以达到通过非交互式的方式创建计划一次性任务的目的。出现 warning 提醒信息,那是 at 命令告诉我们接下来的任务将由 sh 解释器负责执行;与 Bash 解释器基本一致不需要有额外的操作。以上创建了2条重启任务,可以用atrm [任务序列号] 删除不要的任务。
还有一种特殊场景—把计划任务写入 Shell 脚本中,当用户激活该脚本后再开始倒计时执行,而不是像上面那样在固定的时间(“at 23:59”命令)进行。一般会使用“at now +2 MINUTE”的方式进行操作,这表示 2 分钟(MINUTE)后执行这个任务,也可以将其替代成小时(HOUR)、日(DAY)、月(MONTH)等词汇。
如果又希望 Linux 系统能够周期性地、有规律地执行某些具体的任务,可以用 Linux 系统中默认启用的 crond 服务。创建、编辑计划任务的命令为 crontab -e,查看当前计划任务的命令为 crontab -l,删除某条计划任务的命令为 crontab -r。管理员的身份登录的系统,还可以在 crontab 命令中加上-u 参数来编辑其他用户的计划任务。crontab 命令中的参数及其作用如图。
在正式部署计划任务前,还要先了解一下“分、时、日、月、星期 命令”。这是使用 crond 服务设置任务的参数格式。需要注意!如果有些字段没有被设置,则需要使用星号(* )占位如图。
假设在每周一、三、五的凌晨 3:20,都需要使用 tar 命令把某个网站的数据目录进行打包处理,使其作为一个备份文件。可以使用 crontab -e 命令来创建计划任务,为本用户创建计划任务时无须使用 -u 参数。crontab –e 命令的具体实现效果和 crontab -l 命令的结果如下。
除了用逗号(,)来分别表示多个时间段,例如“8,9,12”表示 8 月、9 月 和 12 月。还可以用减号(-)来表示一段连续的时间周期(例如字段“日”的取值为“12-15”,则表示每月的 12到15 共4天)。还可以用除号(/)表示执行任务的间隔时间(例如“*/2”表示每隔 2 分钟执行一次任务)。
如果在 crond 任务中需要同时包含多条计划任务,就需要在下一行新增。例如再添加一条每周一至周五的凌晨 2 点自动清空/tmp 目录内的所有文件。需要注意的是,在 crond 服务的计划任务参数中,所有命令一定要用绝对路径的方式来写,如果不知道绝对路径,可以用 whereis 命令进行查询。
使用计划服务的注意事项:
➢ 在 crond 服务的配置参数中,一般会像 Shell 脚本那样以#号开头写上注释信息,这样在日后回顾这段命令代码时可以快速了解其功能、需求以及编写人员等重要信息。
➢ 计划任务中的“分”字段必须有数值,绝对不能为空或是*号,而“日”和“星期” 字段不能同时使用,否则就会发生冲突。
需要删除 crond 计划任务非常简单,直接使用 crontab -e 命令进入编辑界面,删除里面的文本信息即可。也可以使用 crontab -r 命令直接进行删除即可。
标签:语句,RHEL8Vim,Shell,脚本,用户,命令,Linux,执行 From: https://blog.51cto.com/u_9134612/6236717