zoukankan      html  css  js  c++  java
  • 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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    24)django-信号
    23)django-缓存
    22)django-中间件
    21)django-csrf(跨站请求伪造)
    20)django-session使用
    19)django-cookie使用
    18)django-模板的过滤器和tag,自定义simple_tag和filter
    17)django-模板的继承与导入
    document.documentElement.clientHeight 和 document.body.clientHeight
    Markdown 入门基础
  • 原文地址:https://www.cnblogs.com/dumpling-z/p/11303234.html
Copyright © 2011-2022 走看看