Linux笔记 控制脚本之信号控制作业

目录
①信号基础

②产生信号

③捕捉信号  trap

④运行模式

  后台运行脚本  &

  非控制台下运行脚本  nohup

⑤作业控制

  作业控制只查看作业  jobs

  作业控制之重启停止的作业

    fg命令

    bg命令

 

 

①信号基础
>>>Linux系统上通过Linux信号可以实现对脚本的控制

>>>bash shell会忽略SIGQUIT(3)和SIGTERM(15)的信号,会处理SIGHUP(1)和SIGINT(2)的信号

 

Linux常见的系统信号

常见信号    值        描述

1       SIGHUP     挂起进程

2       SIGINT       终止进程

3          SIGQUIT      停止进程

9         SIGKILL        无条件终止进程

15       SIGTERM     可能的话终止进程

17      SIGSTOP      无条件停止进程但不终止进程

18      SIGSTP        停止或者暂停进程,但不终止进程

19      SIGCONT    继续停止的进程

 

说明:

        当bash shell收到SIGHUP信号时,bash shell会退出,但在退出之前,bash shell会将SIGHUP信号传给shell启动的所有进程(包括shell脚本)

        可以通过SIGINT信号去终端bash shell,当bash shell收到SIGINT信号时,会通知shell启动的所有进程,SIGINT信号意味着Linux内核会停止将CPU处理时间分配给收到该信号的shell

 

 

②产生信号
>>>bash shell允许键盘上的按键组合产生基本的Linux信号

 

产生信号分类    

按键组合    描述

Ctrl+C     发送SIGINT信号到当前正在运行的作业,让作业终止

Ctrl+Z        发送SIGSTP信号,将一个正在前台执行的任务进程放到后台运行,并将任务进程挂起,此时状态为STOP

 

案例

[bei@localhost test]$ sleep 100
^Z
[1]+  Stopped                 sleep 100
[bei@localhost test]$ jobs
[1]+  Stopped                 sleep 100
#停止多个进程后
[beihuatao@localhost ~]$ jobs
[1]   Stopped                sleep 100
[2]   Stopped                 sleep 100
[3]-  Stopped                 sleep 100 : - 表示信号下一个处理的进程
[4]+  Stopped                 sleep 100 : + 表示信号处理的进程

  

说明:

bash shell会将shell中运行的每个进程称为作业(job)

bash shell会为每个作业分配一个唯一的作业号,方括号中[ ]的数字表示的是shell分配的作业号

Stopped表示作业在后台的状态为停止

可以使用ps命令查看已停止的作业,找到对应的PID,可以使用向作业发送SIGKILL信号的方式终止作业

 

案例

[bei@localhost test]$ ps -ef | grep "bei"
root      41490  41466  0 18:43 pts/1    00:00:00 su - bei
bei       41491  41490  0 18:43 pts/1    00:00:00 -bash
root      42614  42231  0 20:13 pts/2    00:00:00 su - bei
bei       42615  42614  0 20:13 pts/2    00:00:00 -bash
bei       42648  42615  0 20:14 pts/2    00:00:00 sleep 100
bei       42781  42615  0 20:36 pts/2    00:00:00 ps -ef
bei       42782  42615  0 20:36 pts/2    00:00:00 grep bei
[bei@localhost test]$ kill -9 42648
[bei@localhost test]$ ps -ef | grep "bei"
root      41490  41466  0 18:43 pts/1    00:00:00 su - bei
bei       41491  41490  0 18:43 pts/1    00:00:00 -bash
root      42614  42231  0 20:13 pts/2    00:00:00 su - bei
bei       42615  42614  0 20:13 pts/2    00:00:00 -bash
bei       42783  42615  0 20:36 pts/2    00:00:00 ps -ef
bei       42784  42615  0 20:36 pts/2    00:00:00 grep bei
[1]+  Killed                  sleep 100
说明:ps命令的第二列为PID,输入kill -9 PID即可终止进程

  

 

③捕捉信号
>>>默认情况下,shell脚本是不会去处理bash shell发送过来的信号

>>>可以使用trap命令指定shell脚本可以捕捉哪些信号

>>>当脚本收到了trap命令中列出的信号,trap命令会组织信号被shell处理,而在本地处理

     例:trap命令可以去监听SIGSTP信号,当脚本收到SIGSTP信号时,trap命令就会捕捉这个信号,让脚本不受影响

 

trap命令基本格式:
trap commands signals

>>>信号以空格分隔开,可以用数值,也可以用名称

>>>commands表示当捕捉到信号,想要执行的shell命令

>>>命令用引号引起来,每次阻止到指定信号,都会执行命令

 

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
trap "echo 'sorry,the signal[Ctrl+C] has been trapped.'" SIGINT
count=1
while [ $count -le 5 ]
do
        echo "sleep $count"
        sleep $count
        count=$[ $count + 1 ]
done
echo "end"
[bei@localhost test]$ bash signal.sh
sleep 1
sleep 2
sleep 3
^Csorry,the signal[Ctrl+C] has been trapped.
sleep 4
^Csorry,the signal[Ctrl+C] has been trapped.
sleep 5
end
说明:

此案例中,使用trap命令去捕捉SIGINT信号,若SIGINT信号被捕捉到,无法终止脚本,而会显示一行文本

  

 

 

④运行模式
>>>大部分情况下,我们执行脚本是在命令行上直接运行,此时我们无法同时使用命令行进行其他操作,只有等待脚本执行结束

>>>当脚本运行时间过长时,如果需要使用命令行做其他事情,我们可以将脚本放入到后台去运行

 

后台运行脚本(与终端关联)
>>>可以使用 bash scripts & 这种方式将scripts脚本放入到后台运行

>>>脚本中的输出(标准输出或标准错误输出)都会打印在屏幕上

>>>每个后台进程都会绑定到该终端的绘画的终端上(pts/0),当终端会话进程退出,会终止该终端后台的进程

 

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
count=1
while [ $count -le 5 ]
do
        echo "sleep $count"
        sleep $count
        count=$[ $count + 1 ]
done
echo "end"
[bei@localhost test]$ bash signal.sh &
[1] 43055
[bei@localhost test]$ sleep 1
sleep 2
sleep 3
sleep 4
[bei@localhost test]$
[bei@localhost test]$ ls -al
total 100
drwxrwxr-x. 2 bei bei 4096 Sep 25 21:10 .
drwxr-xr-x. 6 bei bei 4096 Sep 16 19:51 ..
-rw-rw-rw-. 1 bei bei  120 Sep 25 21:10 signal.sh
[bei@localhost test]$ sleep 5
pwd
/home/bei/linux/test
[bei@localhost test]$ end
[1]+  Done                    bash signal.sh
说明:

当脚本放入到后台执行时会有一个输出,如[1] 43055,
其中[1]表示的是当前bash shell给这个作业分配的作业号,4305表式 分配给脚本的进程号PID

当脚本结束后,会有一个输出,如
[1]+ Done bash signal.sh 表示脚本已结束

  

    

非控制台下运行脚本(与终端不关联)
>>>需求:即使终端会话进程退出,在后台运行的脚本也不会退出,一直运行直到脚本自身运行完成

>>>可以使用nohup命令:nohup bash scripts &

>>>不会有标准输出和标准错误输出,而将输出追加式重定向到nohup.out 文件中(输出追加到此文件中,不删除原来的内容)

>>>nohup bash scripts> myout.file 2>&1 &             #重定向到指定文件

 

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
count=1
while [ $count -le 5 ]
do
        echo "sleep $count"
        sleep $count
        count=$[ $count + 1 ]
done
echo "end"
[bei@localhost test]$ nohup bash signal.sh  &
[1] 43155
[bei@localhost test]$ nohup: ignoring input and appending output to `nohup.out'
[bei@localhost test]$
[bei@localhost test]$ jobs
[1]+  Running                 nohup bash signal.sh &
[bei@localhost test]$
[1]+  Done                    nohup bash signal.sh
[bei@localhost test]$ ls -al ./nohup.out
-rw-------. 1 bei bei 88 Sep 25 21:26 ./nohup.out
[bei@localhost test]$ cat ./nohup.out
sleep 1
sleep 2
sleep 3
sleep 4
sleep 5
end

  


 

 

⑤作业控制
>>>作业控制:启动、停止、无条件终止以及恢复作业等功能

 

作业控制只查看作业
>>>可以使用jobs命令查看后台进程

[bei@localhost test]$ bash signal.sh
^Z
[1]+  Stopped                 bash signal.sh
[bei@localhost test]$ bash signal.sh &
[2] 43611
[bei@localhost test]$ jobs
[1]+  Stopped                 bash signal.sh
[2]-  Running                 bash signal.sh &

说明:

>>>对于作业[1]使用Ctrl+z挂起,在jobs中显示Stopped表示作业已经暂时挂起

>>>对于作业[2],使用在执行脚本命令后面加上&符号,使它在后台运行,在jobs中显示Running表示作业正在运行中

>>>作业号的右边有加号"+"和减号"-",带加号的作业表示默认作业,表示使用作业控制命令时,未在命令行上指定作业号则默认操作的是带加号的作业;带减号的作业是带加号的作业的备胎,比如kill掉作业[1],原来带减号的作业[2]的减号就变成了加号

 

jobs命令相关选项说明

参数      描述

-l        列出进程的PID和对应的作业号

-n      只列出上次shell发出的通知后改变状态的作业

-p      只列出作业的PID

-r       列出处于运行状态的作业

-s      列出处于暂停状态的作业

 

批量kill后台的正在运行的所有进程

a= `jobs -p`                                #将所有进程的PID赋予给变量a

for i in $a;do kill $i;done      #如果想要kill后台所有进程,包括stopped的进程,使用-9参数,无条件终止进程(慎用)

 

终止后台指定作业号的作业:kill %number    (建议用作业号的方式kill,不用PID的方式)

[bei@localhost test]$ jobs
[1]-  Stopped                 bash signal.sh
[2]+  Stopped                 bash signal.sh
[3]   Running                 bash signal.sh &
[bei@localhost test]$ kill %3
[bei@localhost test]$ jobs
[1]-  Stopped                 bash signal.sh
[2]+  Stopped                 bash signal.sh
[3]   Terminated              bash signal.sh
注意:可以输入命令 kill %

不指定作业号,则kill的作业是带加号的作业

  

 

作业控制之重启停止的作业


>>>fg命令:将后台进程调至前台运行
fg number            (如果不加number,默认操作的是有+的作业)

 

案例

[bei@localhost test]$ cat signal.sh
#!/bin/bash
count=1
while [ $count -le 5 ]
do
        echo "$count second sleep"
        sleep 1
        count=$[ $count + 1 ]
done
echo "End"
[bei@localhost test]$ bash signal.sh
1 second sleep
2 second sleep
3 second sleep
^Z
[1]+  Stopped                 bash signal.sh
[bei@localhost test]$ fg 1
bash signal.sh
4 second sleep
5 second sleep
End

 

 

>>>bg命令:将挂起的进程在后台启动为运行状态:
bg number    (如果不加number,默认操作的是有+的作业 )

 

案例

[bei@localhost test]$ bash signal.sh
1 second sleep
^Z
[1]+  Stopped                 bash signal.sh
[bei@localhost test]$ bg 1
[1]+ bash signal.sh &
[bei@localhost test]$ 2 second sleep
3 second sleep
jobs
[1]+  Running                 bash signal.sh &   #输入jobs查看到作业正在后台运行,输出在屏幕上
[bei@localhost test]$ 4 second sleep
5 second sleep
End

[1]+  Done                    bash signal.sh

  


 

 ⑥调整谦让度

>>>在多任务操作系统中(如Linux),内核负责将CPU时间分配给系统上运行的每个进程。

>>>调度优先级是内核分配给进程的CPU时间。调度优先级是个整数值,从-20(最高优先级)到+19(最低优先级)。默认情况下,bash shell以优先级0来启动所有进程。

>>>使用nice命令可以修改一个shell脚本的优先级。调整已启动进程的nice值用renice

 

nice命令:设置命令启动时的调度优先级

nice  -优先级 SCRIPT | COMMON   

nice  -n  优先级 SCRIPT | COMMON  

说明:

nice命令阻止普通用户提高命令的优先值。

查看进程ni值

ps -ef  -o pri,ni,pid,comm

 

renice命令:允许指定运行进程的PID来改变优先级。

renice -n  优先级 -p PID

 

renice命令会自动更新当前运行进程的调度优先级。和nice命令一样,renice命令也有一些限制

  只能对属于本地用户的进程执行renice

  只能通过renice降低进程的优先级

  root用户可以通过renice来任意调整进程的优先级。

 

 

 

 

---------------------
作者:Mr_Bei
来源:CSDN
原文:https://blog.csdn.net/mr_bei/article/details/82855180
版权声明:本文为博主原创文章,转载请附上博文链接!

posted @ 2019-08-05 15:26  一只废饺  阅读(305)  评论(0编辑  收藏  举报