管理系统进程
操作系统管理多个用户的请求和多个任务。大多数系统都只有一个 CPU 和一个主要存储,但一个系统可能有多个二级存储磁盘和多个输入/输出设备。操作系统管理这些资源并在多个用户间共享资源,当用户提出一个请求时,造成好像系统被用户独占的假象。实际上操作系统监控着一个等待执行的任务队列,这些任务包括用户任务、操作系统任务、邮件和打印任务等。本节将从用户的角度讲述如何控制进程。
调度启动进程
有时候需要对系统进行一些比较费时而且占用资源的维护工作,这些工作适合在深夜进行,这时候用户就可以事先进行调度安排,指定任务运行的时间或者场合,到时候系统会自动完成这些任务。要使用自动启动进程的功能,就需要掌握以下几个启动命令。
定时运行一批程序(at)
at 命令
用户使用 at 命令在指定时刻执行指定的命令序列。该命令至少需要指定一个命令和一个执行时间。at 命令可以只指定时间,也可以时间和日期一起指定。
at 命令的语法格式如下:
at [-V] [-q 队列] [-f 文件名] [-mldbv] 时间
at -c 作业 [作业…]
设置时间
at 允许使用一套相当复杂的时间指定方法,比如:
- 接受在当天的 hh:mm(小时:分钟)式的时间指定。如果该时间已经过去,那么就放存第二天执行。
- 使用 midnight(深夜)、noon(中午)、teatime(饮茶时间,一般是下午 4点)等比较模糊的词语来指定时间。
- 采用 12 小时计时制,即在时间后面加上 AM(上午)或者 PM(下午)来说明是上午还是下午。
- 指定命令执行的具体日期,指定格式为 month day(月日)或者 mm/dd/yy(月/日/年)或者 dd.mm.yy(日.月.年)。指定的日期必须跟在指定时间的后面。
上面介绍的都是绝对计时法,其实还可以使用相对计时法,这对于安排不久就要执行的命令是很有好处的。指定格式为 now+count time-units,now 就是当前时间,time-units 是时间单位,这里可以是 minutes(分钟)、hours(小时)、days(天)、weeks(星期)。count 是时间的数量,究竟是几天,还是几小时等。还有一种计时方法就是直接使用 today(今天)、tomorrow(明天)来指定完成命令的时间。下面通过一些例子来说明具体用法。
例如指定在今天下午 4:30 执行某个命令。假设现在时间是中午 12:30,2019 年 6 月 7 日,可用命令格式如下:
at 4:30pm
at 16:30
at 16:30 today
at now+4 hours
at now+ 240 minutes
at 16:30 7.6.19
at 16:30 6/7/19
at 16:30 Jun 7
以上这些命令表达的意义是完全一样的,所以在安排时间的时候完全可以根据个人喜好和具体情况自由选择。一般采用绝对时间的 24 小时计时法可以避免由于用户自己的疏忽造成计时错误,例如上例可以写成:at 16:30 6/7/19。
执行权限
对于 at 命令来说,需要定时执行的命令是从标准输入或者使用 -f 选项指定的文件中读取并执行的。如果 at 命令是从一个使用 su 命令切换到用户 shell 中执行的,那么当前用户被认为是执行用户,所有的错误和输出结果都会送给这个用户。但是如果有邮件送出的话,收到邮件的将是原来的用户,也就是登录时 shell 的所有者。
例如在 6 月 8 日上午 10 点执行 slocate -u 命令。命令如下:
# at 10:00 6/8/19
at> slocate -u
at>
[1]+ Stopped at 10:00 6/8/19
上面的结果中,输入 at 命令之后,会出现提示符 at>,提示用户输入命令,在此输入了 slocate -u,然后按回车键。还可以输入多条命令,当所有要执行的命令输入结束后,按 Ctrl+d 键结束 at 命令。
在任何情况下,管理员账户都可以使用这个命令。对于其他用户来说,是否可以使用就取决于 /etc/at.allow 和 /etc/at.deny 文件。
周期性运行一批程序(cron)
前面介绍 at 命令都会在一定时间内完成一定任务,但是它只能执行一次。也就是说,当指定了运行命令后,系统在指定时间完成任务,以后就不再执行了。但是在很多情况下需要周期性重复执行一些命令,这时候就需要使用 cron 命令来完成任务。
运行机制
首先 cron 命令会搜索 /var/spool/cron 目录,寻找以 /etc/passwd 文件中的用户名命名的 crontab 文件,被找到的这种文件将装入内存。比如一个用户名为 globus 的用户,对应的 crontab 文件应该是 /var/spool/cron/globus,即以该用户命名的 crontab 文件存放在 /var/spool/cron 目录下面。
cron 命令还将搜索 /etc/crontab 文件,这个文件是用不同的格式写成的。cron 启动以后,它将首先检查是否有用户设置了 crontab 文件,如果没有就转入睡眠状态,释放系统资源。所以该后台进程占用资源极少,它每分钟被换醒一次,查看当前是否有需要运行的命令。
命令执行结束后,任何输出都将作为邮件发送给 crontab 的所有者,或者是 /etc/crontab 文件中 MAILTO 环境变量中指定的用户。这是 cron 的工作原理,但是 cron 命令的执行不需要用户干涉,用户只需要修改 crontab 中要执行的命令。
crontab 命令
crontab 命令用于安装、删除或者显示用于驱动 cron 后台进程的表格。用户把需要执行的命令序列放到 crontab 文件中以获得执行,而且每个用户都可以有自己的 crontab 文件。
crontab 命令的常用方法如下:
- crontab -u //设置某个用户的 cron 服务,root 用户在执行 crontab 时需要此参数。
- crontab -l //列出某个用户 cron 服务的详细内容。
- crontab -r //删除某个用户的 cron 服务。
- crontab -e //编辑某个用户的 cron 服务。
例如 root 查看自己的 cron 设置。命令如下:
crontab -u root -l
crontab 文件
在 crontab 文件中输入需要执行的命令和时间。该文件中每行都包括6个域,其中前5个域是指定命令被执行的时间,最后一个域是要被执行的命令。每个域之间使用空格或者制表符分隔。格式如下:
minute hour day-of-month month-of-year day-of-week commands
对于每一项的说明如所示。
表 1 参数说明
参数 | 描述 |
---|---|
minute | 分钟(0~59)。 |
hour | 小时(0~23)。 |
day-of-month | 一个月的第几天(1~31)。 |
month-of-year | 一年的第几个月(1~12)。 |
day-of-week | 一周的星期几(0~6),0代表星期天。 |
commands | 需要执行的命令。 |
这些项都不能为空,必须指定值。除了数字还有几个特殊的符号“”、“/”和“-”、“,”。其中,代表所有的取值范围内的数字,/代表每的意思,“*/5”表示每5个单位,“-”代表从某个数字到某个数字,“,”分开几个离散时数字。对于要执行的命令,调用的时候需要写出命令的完整路径。
例如晚上 18 点到 22 点之间每两个小时,在 /tmp/test.txt 文件中加入 sleepy 文本。在 crontab 文件中对应的行如下:
* 18-22/2 * * * echo "sleepy" >> /tmp/test.txt
每次编辑完某个用户的 cron 设置后,cron 自动在 /var/spool/cron 下生成一个与此用户同名的文件。此用户的 cron 信息都记录在这个文件中,这个文件是不可以直接编辑的,只可以用 crontab -e 来编辑。用户也可以另外建立一个文件,使用“cron文件名”命令导入 cron 设置。
假设有个用户名为 globus,它需要为自己创建的一个 crontab 文件。步骤如下:
首先可以使用任何文本编辑器建立一个新文件,并将向该文件加入需要运行的命令和要定期执行的时间,假设该文件为 ~/globus.cron。
然后使用 crontab 命令安装这个文件,使用 crontab 命令使之成为该用户的 crontab 文件。命令如下:
crontab globus. ~/globus.cron
这样 crontab 文件就建立好了,可以转到 /var/spool/cron 目录下面查看,发现多了一个 globus 文件。这个文件就是所需的 crontab 文件。
说明:
cron 启动后,每过一分钟读一次 crontab 文件,检查是否要执行里面的命令。因此该文件被修改后不需要重新启动 cron 服务。
编辑配置文件
cron 服务每分钟不仅要读一次 /var/spool/cron 内的所有文件,还需要读一次 /etc/crontab,因此通过配置这个文件也能得到 cron 的服务。用 crontab 配置是针对某个用户的,而编辑 /etc/crontab 是针对系统的任务。此文件的文件格式如下:
SHELL=/bin/sh
PATH=/usr/bin:/usr/sbin:/sbin:/bin:/usr/lib/news/bin
MAILTO=root //如果出现错误,或者有数据输出,数据作为邮件发给这个账号
HOME=/
# run-parts
01 * * * * root run-parts /etc/cron.hourly //每个小时执行一次/etc/cron.hourly里的脚本
02 4 * * * root run-parts /etc/cron.daily //每天执行一次/etc/cron.daily里的脚本
22 4 * * 0 root run-parts /etc/cron.weekly //每周执行一次/etc/cron.weekly里的脚本
42 4 1 * * root run-parts /etc/cron.monthly //每月执行一次/etc/cron.monthly里的脚本
说明:
如果去掉 run-parts 参数,其后面就是运行的某个脚本名,而不是目录名。
挂起/恢复进程
作业控制允许进程挂起并可以在需要时恢复进程的运行,被挂起的作业恢复后将从中止处开始继续运行。只要在键盘上按 Ctrl+Z 键,即可挂起当前的前台作业。在键盘上按 Ctrl+Z 键后,将挂起当前执行的命令 cat。使用 jobs 命令可以显示 shell 的作业清单,包括具体的作业、作业号以及作业当前所处的状态。
恢复进程执行时,有两种选择:用 fg 命令将挂起的作业放回到前台执行;用 bg 命令将挂起的作业放到后台执行。灵活使用上述命令,将给自己带来很大的方便。