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
    版权声明:本文为博主原创文章,转载请附上博文链接!

  • 相关阅读:
    mysql报错:java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more than one time zone.
    MD5登陆密码的生成
    15. 3Sum、16. 3Sum Closest和18. 4Sum
    11. Container With Most Water
    8. String to Integer (atoi)
    6. ZigZag Conversion
    5. Longest Palindromic Substring
    几种非线性激活函数介绍
    AI初探1
    AI初探
  • 原文地址:https://www.cnblogs.com/dumpling-z/p/11303234.html
Copyright © 2011-2022 走看看