Linux脚本的运行控制

转载:https://mp.weixin.qq.com/s/VbpxFnt-_vyYlLOyFbGB8A

00

Shell脚本的运行控制

 

我们已经知道如何启动shell脚本,但是脚本一旦“启动”,我们如何对脚本进行运行控制了?比如,如何暂停、停止、继续运行一个进程;通过本文的介绍,答案将一一揭晓。

 

01

 

信号处理机制

 

Linux系统通过信号实现进程间的通信。编程用户可以利用这些不同的信号,响应执行不同的命令,实现对shell脚本的控制运行。

 

1.1 重要的Linux信号

 

下表罗列了Linux Shell编程中可能会遇到的最常见的信号。

 

信号值

助记符

描述

1

SIGHUP

挂起进程

2

SIGINT

终止进程

3

SIGQUIT

停止进程

9

SIGKILL

无条件终止进程

15

SIGTERM

可能的化终止经常

17

SIGSTOP

无条件停止进程,但不是终止进程

18

SIGTSTP

停止或暂停进程,但不终止进程

19

SIGCONT

继续运行停止的进程

 

shell会将这些信号传给shell脚本程序来处理,而shell脚本的默认行为是忽略这些信号,要避免这种情况,我们可以在脚本中加入识别信号和处理信号的命令。

 

1.2 产生信号

 

bash shell支持利用键盘组合键生成两种基本的Linux信号,用于终止和暂停进程:

  • 终止进程:Ctrl+C组合键产生SIGINT信号,并将其发送给shell中当前运行的所有进程

  • 暂停进程:Ctrl+Z组合键产生SIGTSTP信号,用于暂停shell中运行的所有进程。暂停进程会让程序驻留在内存中,并能从上次停止的位置继续运行

 

1.3 捕捉信号

 

信号产生以后,我们可以忽略信号,也可以利用Linux提供的trap命令捕捉信号并执行相应的响应命令。

 

格式:trap commands signals

 

在上述的命令格式中,signals是一组用空格分开的需要捕捉的信号;commands是捕捉到相应信号后想要执行的shell命令。示例如下:

 

 

1.4 捕捉脚本的退出

 

格式:trap commands  EXIT

 

在上述的命令格式中,当shell脚本正常或异常退出,均可触发执行commands命令。这是在shell完成任务时执行命令的最简易的方法。如下示例示范了shell正常运行与提前退出,均执行了特定命令:

 

 

1.5 移除信号捕捉

 

格式:trap -  singal

 

在上述格式中,trap命令后跟着一个单破折线,然后是要移除的信号,将其恢复到正常状态;一旦信号捕捉被移除了,脚本会忽略该信号。但是,如果在捕捉被移除前收到信号,脚本就会在trap命令中处理它。

 

02

 

后台运行脚本

 

 

在脚本在终端启动后,会一直占用运行脚本的终端。如果脚本运行时间很长,那么该终端就会一直被占用。Linux系统提供了脚本后台运行模式;该该模式中,进程运行时不会和终端会话上的STDIN、STDOUT和STDERR关联,允许它们在后台运行而不用占用终端会话。

 

(1)格式:command  &

 

以后台模式运行shell脚本,只需要在命令后加个&符即可。

 

如上所示,以后台模式运行脚本后,输出的第一行信息为[1] 634;方括号中的数字是shell分配给后台进程的作业号;第二个数是Linux系统分配给进程的进程ID(PID)。此外,当后台进程在运行时,仍然会使用终端显示器来显示STDOUT和STDERR消息。

 

注意:每个后台进程都会与运行进程的终端会话相绑定;如果显示终端退出了,那么该后台进程也会退出。

 

(2)格式:nohup command  &

 

nouhup命令运行了另外一个命令来阻断所有发送给进程的SIGHUP信号。这会在退出终端会话时阻止进程退出。上述命令格式与普通后台进程最重要的区别在于:前者即使终端会话退出了,进程仍然会继续执行直到完成。

 

由于nohup命令会从终端解除进程的关联,进程会丢掉STDOUT和STDERR的链接。为了保存该命令的输出,nohup命令会自动将STDOUT和STDERR的消息重定向到一个名外nohup.out的文件。

 

注意:当在同目录下同时运行多个nohup命令时,这些所有运行的命令输出会全部追加到同一个nohup.out文件中。

 

03

 

作业控制

 

前面我们介绍到可以通过组合键来停止shell中正在运行的作业;在作业停止后,我们可以终止或重启它。启动、停止、无条件终止以及恢复作业的这些功能统称为作业控制。通过作业控制,我们就能完全控制shell中正在运行的所有作业。

 

3.1 查看作业

 

格式:jobs [option] [jobID]

 

jobs命令可以查看shell当前正在处理的作业。

 

从上面的执行例子中,我们可以发现结果输出中有+和-;带加号的作业会被当做默认的作业。在使用作业命令的时候,如果未在命令行指定任何作业号,控制控制的对象均为默认的作业。任何时候都只会有一个带+的作业和一个带-的作业;当默认作业完成处理时,带-的作业会成为下一个默认作业。

 

3.2 重启停止的作业

 

在bash作业控制中,我们可以将已停止的作业作为后台进程或前台进程重启;重启后的前台进程会接管当前工作的终端。

 

格式:bg [jobID]

 

上述命令能够实现以后台模式重启一个作业。并且,由于作业是以后台模式重启的,命令行界面的提示符会出现,允许输入其他命令。

 

格式:fg [jobID]

 

上述命令能够实现以前台模式重启一个作业。并且,由于作业是以前台模式重启的,命令行界面的提示符不会出现,直到该作业运行完成。

 

04

 

调整运行优先级

 

现代操作系统基本都是采用时间片轮转的方法调度进程;而在时间片到达的时候,优先调用进程等待队列中优先级高进程;在Linux操作系统中,调度优先级是一个从-20(最低优先级) ~ +19(最高优先级)的整数值,也就是整数值越小,进程的调度优先级就越高。默认情况下,bash shell以优先级0来启动所有进程。

 

4.1 nice命令

 

格式:nice -n pri command

 

nice命令可以实现命令启动时调整一个命令的调度优先级;-n选项允许以更低的优先级运行命令;如果想要增加运行命令的优先级,系统会报错。

 

4.2 renice命令

 

格式:renice pri -p pid

 

renice命令可以改变已启动运行的进程的优先级;使用该命令需要注意以下事项:

  • 该命令只能对属主进程有效

  • 该命令只能降低进程的优先级

  • root用户通过该命令可以调整任何进程的优先级到任何级别

 

05

 

定时运行作业

 

定时运行作业在很多业务场景都有应用。Linux系统提供了多个在预定时间运行脚本的方法:at命令和cron表。

 

5.1 at命令

 

格式:at [-f filename] time

 

该命令中用-f参数来指定读取命令(脚本文件)的文件名。time参数指定了Linux系统何时运行该作业,具体的时间格式有:

  • 标准的小时和分钟格式,如09:30

  • ~AM/~PM指示符,比如09:30~PM

  • 特定可命令的时间,比如now/noon/midnight/teatime

  • 如果指定了一个已经过去的时间,at命令会在第二天该时间运行该作业

  • 标准日期格式,比如MMDDYY、MM/DD/YY或DD.MM.YY

  • 也可指定时间增量:当前时间+25min;明天10:15~PM;10:15+7天



     

5.2 cron表

 

at命令常用于在预定时间执行脚本;如果需要脚本按照一定时间频率重复执行命令则推荐使用cron时间表。

 

cron时间表的格式如下:

格式:min hour dayofmonth month dayofweek  command

 

cron时间表允许你使用特定值、值范围或者是通配符(*)来指定条目。min、hour分别用于设置分钟、小时;我们可以用三字符的文本值(mon、tue、wed、thu、fri、sat、sun)或数值(0为周末,6为周六)来指定dayofweek条目。

 

示例:

15 10  * * * command    表示在每天10:15运行命令

15 10 1 * * command    表示在每月的第一天10:15运行命令

 

格式:crontab option

option为命令选项,解释如下:

-e:实现对cron时间表进行编辑

-l:显示已有的时间表

 

cron程序是假定Linux系统7x24小时运行的。如果在cron时间表中的作业计划运行时间内Linux系统被关闭,那作业就不会运行了。当系统开机时,cron程序不会回去再运行那些错过的作业。anacron程序可以有效解决这些问题。

 

anacron会尽快运行错过了计划的作业。anacron程序只会处理位于cron目录的程序,比如/etc/cron.monthly。它用时间戳来决定作业何时被运行。每个cron目录都有个时间戳,位于/var/spool/anacron。

 

anacron时间表的格式如下:

格式:period delay identifier command

 

其中,period定义了作业多久运行一次,以天为单位;delay条目指定系统启动后多少分钟后anacron程序开始运行错过的脚本;identifier是一个非空白字符串,如cron.weekly,用于唯一标识日志消息。

 

注意:anacron不会运行位于/etc/cron.hourly的脚本,这是因为anacron程序不会处理执行时间需求小于一天的脚本。

 

06

 

开机运行脚本

 

Linux支持当系统开机时或用户刚启动一个新的bash shell会话时启动命令。

 

不同的Linux发行版提供了不同的开机运行文件,我们可以将一些命令写入开机运行文件,实现当系统开机时自动运行这些命令。

  • debian    :    /etc/rc.local

  • Ubuntu    :    /etc/init.d/rc.local

  • Fedora    :    /etc/rc.d/rc.local

  • OpenSuse    :    /etc/init.d/boot.local

 

每个用户的主目录下都有两个文件,bash shell会用它们来自启动脚本并设置环境变量:

  • .bash_profile

  • .bashrc

 

当新shell是新的登录生成的话,bash shell会运行.bash_profile文件。可以把任何登录时要运行的脚本放入该文件。

 

当新shell启动时,包括有新的登录的情况,bash shell会运行.bashrc文件。

 

如果我们想为系统中的所有用户运行一个脚本,我们可以在/etc/bashrc文件中加入要运行的脚本。

 

注意:以上脚本命令需编写完整路径。

 

07

 

小结

  

综上,本文对shell的运行控制若干技术进行了介绍。

 

Linux系统通过对shell脚本发送信号实现对脚本的运行控制。shell脚本能够接受外部信号进而实现终止、暂停一个正在运行的进程;并可以通过trap语句来捕捉信号并执行自定义的特定命令。

 

我们可以通过在执行的命令后添加一个&符号来让脚本或命令以后台模式运行;以后台模式运行命令或脚本时,交互式shell会返回,允许用户在控制台终端继续输入其他命令;后台运行的命令会绑定到该终端会话,如果退出了终端会话,后台进程也会随即终止。

 

Linux提供了nohup命令,可以阻止上述情况发生。该命令能拦截任何能停止shell命令的信号。这样,即使已经退出了运行该shell命令的会话终端,shell仍会继续执行。

 

Linux提供了强大的作业控制能力。jobs命令可以查看该shell会话启动的进程。对于已经停止的作业,利用bg命令可以以后台模式重启一个作业;要以前台模式重启作业,则需使用fg命令。nice命令和renice命令允许你调整进程的优先级。通过降低进程的优先级,可以让CPU给该进程分配更少的时间。

 

除了能够对进程进行运行控制外,还可以对shell脚本何时启动进行设定;其中,at命令允许你在预设时间运行脚本;cron程序则提供了周期性运行脚本的接口。

 

最后,Linux提供了在系统开机或用户启动新bash shell时运行自定义脚本的机制。各个Linux发行版提供了不同的文件接口在系统每次开机时,允许运行用户自定义脚本;此外,用户家目录下的.bas_profile文件会在用户每次登录到系统时运行脚本;.basrc文件会在启动每个shell实例时运行脚本。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值