美文网首页Lunix学习
第二十八课 LinuxShell编程六之控制脚本

第二十八课 LinuxShell编程六之控制脚本

作者: Arroganter | 来源:发表于2018-09-05 16:06 被阅读15次

    说明:本文部分内容均摘取自书籍《Linux命令行与shell脚本编程大全》,版权归原作者所有。《Linux命令行与shell脚本编程大全》(第三版)第十六章学习总结

    第十六章:控制脚本

    本章内容

    处理信号
    以后台模式运行脚本
    禁止挂起
    作业控制
    修改脚本优先级
    脚本执行自动化
    
    

    16.1 处理信号

    16.1.1 重温Linux信号

    Linux系统信号

    Linux利用信号与运行在系统中的进程进行通信
    可以使用信号来停止/启动/终止进程
    可以通过对脚本进行编程,使其在收到特定信号时执行某些命令,从而控制shell脚本
    默认情况下,bash shell会忽略收到的任何3和15信号
    但是bash shell会处理1和2信号
    
    

    常见的Linux系统信号

    信号:值:描述
    1:SIGHUP:挂起进程
    2:SIGINT:终止进程
    3:SIGQUIT:停止进程
    9:SIGKILL:无条件终止进程
    15:SIGTERM:尽可能终止进程
    17:SIGSTOP:无条件停止进程,但不是终止进程
    18:SIGTSTP:停止或暂停进程,但不终止进程
    19:SIGCONT:继续运行停止的进程
    
    

    16.1.2 生成信号

    1.中断进程

    使用Ctrl+C组合键会生成2(SIGINT)信号,并将其发送给当前在shell中运行的所有进程

    执行命令

    sleep 100
    ^C
    
    

    注:^代指Ctrl键

    2.暂停进程

    使用Ctrl+Z组合键会生成18(SIGTSTP)信号,停止shell中运行的任何进程

    执行命令

    sleep 100
    ^Z
    
    

    当按键Ctrl+Z组合键时,bash shell会给出如下提示

    [1]+  Stopped sleep 100
    方括号中的数字时shell分配的作业号(job number)
    shell将shell中运行的每个进程称为作业,并为每个作业分配唯一的作业号
    如果shell回话中有已停止的作业,在退出shell时,bash会提醒你
    
    

    常用操作

    ps -l
    查看已停止的作业,在S列中(进程状态)显示T的为已停止的作业
    kill -9 PID
    终止指定PID的作业,终止已停止作业的PID
    通俗来讲,就是杀掉进程
    
    

    16.1.3 捕获信号

    命令格式:trap commands signals
    命令说明:使用trap命令来指定shell脚本要监看并从shell中拦截的Linux信号

    使用trap命令来忽略SIGINT信号

    编写test1.sh脚本

    #!/bin/bash
    
    trap "echo 'Sorry!I have trappend Ctrl-C'" SIGINT
    
    echo This is a test script
    
    count=1
    while [ $count -le 10 ]
    do
        echo "Loop #$count"
        sleep 1
        count=$[ $count+1 ]
    done
    
    echo "This is the end of the test script"
    
    

    16.1.4 捕获脚本退出

    捕获shell脚本的退出EXIT信号

    编写test2.sh脚本

    #!/bin/bash
    
    trap "echo Goodbye..." EXIT
    
    count=1
    while [ $count -le 5 ]
    do
        echo "Loop #$count"
        sleep 1
        count=$[ $count+1 ]
    done
    
    

    16.1.5 修改或移除捕获

    修改信号捕获,脚本仍然会根据最初的trap命令进行处理

    编写test3.sh脚本

    #!/bin/bash
    #
    trap "echo 'Sorry.. Ctrl+C is trapped.'" SIGINT
    #
    count=1
    while [ $count -le 5 ]
    do
        echo "Loop #$count" 
        sleep 1
        count=$[ $count+1 ]
    done
    #
    trap "echo 'I modified the trap!'" SIGINT
    #
    count=1
    while [ $count -le 5 ]
    do
        echo "Loop #$count" 
        sleep 1
        count=$[ $count+1 ]
    done
    
    

    在trap和信号列表之间加上两个破折号删除已设置好的捕获并恢复默认行为

    编写test3b.sh脚本

    #!/bin/bash
    #
    trap "echo 'Sorry.. Ctrl+C is trapped.'" SIGINT
    #
    count=1
    while [ $count -le 5 ]
    do
        echo "Loop #$count" 
        sleep 1
        count=$[ $count+1 ]
    done
    #
    # Remove the trap
    trap -- SIGINT
    echo "I just removed the trap"
    #
    count=1
    while [ $count -le 5 ]
    do
        echo "Loop #$count" 
        sleep 1
        count=$[ $count+1 ]
    done
    
    

    敲门:也可以在trap命令后使用单破折号来恢复信号的默认行为。单破折号和双破折号都可以正常发挥作用

    16.2 以后台模式运行脚本

    16.2.1 后台运行脚本

    在命令后加个&符以后台模式运行shell脚本

    编写test4.sh脚本

    #!/bin/bash
    count=1
    while [ $count -le 10 ]
    do
        sleep 1
        count=$[ $count+1 ]
    done
    
    

    执行命令

    ./test4.sh &
    
    

    然后显示[1] 3231
    方括号中的表示后台进程的作业号,后面的数字为进程的进程ID(PID)

    当后台进程运行时,它仍然会使用终端显示器来显示STDOUT和STDERR消息

    编写test5.sh脚本

    #!/bin/bash
    #
    echo "Start the test script"
    count=1
    while [ $count -le 5 ]
    do
        echo "Loop #$count"
        sleep 5
        count=$[ $count+1 ]
    done
    #
    echo "Test script is complete"
    
    

    当脚本在后台模式运行时,脚本的输出和输入的命令以及命令输出全都混在了一起,最好是将后台运行的脚本的STDOUT和STDERR进行重定向,避免杂乱的输出

    16.2.2 运行多个后台作业

    可以使用&符号的方法在命令行提示符下同时启动多个后台作业
    使用ps命令查看所有脚本的运行状态
    在终端会话中使用后台进程时一定要小心,当退出终端时,后台进程也会退出
    
    

    16.2.3 在非控制台下运行脚本

    命令格式:nohup ./test1.sh &
    命令说明:使用nohup命令在终端会话中启动shell脚本,并让脚本一直以后台模式运行到结束,即使退出了终端会话,shell脚本也会一直运行

    执行命令

    nohup ./test1.sh &
    cat nohup.out
    
    

    说明

    使用nohup启动shell脚本时,脚本会忽略终端会话发过来的SIGHUP信号
    由于nohup命令会解除终端与进程的关联,进程也就不在同STDOUT和STDERR关联
    nohup命令会自动将STDOUT和STDERR的消息重定向到当前目录下名为nohup.out的文件中
    如果使用nohup命令运行了另一个脚本,则该脚本的输出会被追加到已有的nohup.out文件中
    
    

    16.4 作业控制

    启动/停止/终止以及恢复作业的这些功能统称为作业控制

    16.4.1 查看作业

    使用jobs命令查看shell当前正在处理的作业,脚本$$变量显示Linux系统分配给该脚本的PID

    编写test10.sh脚本

    #!/bin/bash
    #
    echo "Script Process ID: $$"
    #
    count=1
    while [ $count -le 10 ]
    do
        echo "Loop #$count"
        sleep 10
        count=$[ $count + 1 ]
    done
    #
    echo "End of script..."
    #
    
    

    执行命令

    ./test10.sh > test10.out &
    查看作业
    jobs
    查看作业的PID
    jobs -l
    
    

    jobs命令参数

    参数:描述
    -l:列出进程的PID以及作业号
    -n:只列出上次shell发出的通知后改变了状态的作业
    -p:只列出作业的PID
    -r:只列出运行中的作业
    -s:只列出已停止的作业
    
    

    jobs命令输出中的加号和减号

    带加号的作业会被当做默认作业
    在使用作业控制命令时,如果未在命令行指定任何作业号,
        该作业会被当做作业控制命令的操作对象
    当前的默认作业完成处理后,带减号的作业成为下一个默认作业
    任何时候都只有一个带加号的作业和一个带减号的作业,
        不管shell中有多少个正在运行的作业
    
    

    16.4.2 重启停止的作业

    命令格式:bg 作业号
    命令说明:以后台模式重启指定作业
    命令格式:fg 作业号
    命令说明:以前台模式重启指定作业

    16.6 定时运行作业

    16.6.1 用at命令来计划执行作业

    1.at命令的格式

    命令格式:at [-f filename] time
    命令说明:使用-f参数指定需要执行的脚本文件的文件名,time参数制定了什么时候运行

    多种不同的时间格式

    标准的小时和分钟格式,比如10:15
    AP/PM指示符,比如10:15PM
    特定可命名时间,比如now,noon,midnight或teatime(4PM)
    标准日期格式,比如MMDDYY,MM/DD/YY或DD.MM.YY
    文本日期,比如Junl4或Dec25,加不加年份均可
    也可以指定时间增量
        当前时间+25min
        明天10:15PM
        10:15+7天
    
    

    2.获取作业的输出

    在Linux系统上运行时,显示器并不会关联到该作业。Linux系统会将STDOUT或STDERR的输出通过邮件系统发送给用户

    编写test13.sh脚本

    #!/bin/bash
    echo "This script ran at $(date +%B%d,%T)"
    echo
    sleep 5
    echo "This is the script end..."
    
    

    执行命令

    at -f test13.sh now
    
    

    使用-M选项来屏蔽作业产生的输出信息

    编写test13b.sh

    #!/bin/bash
    echo "This script ran at $(date +%B%d,%T)" > test13b.out
    echo >> test13b.out
    sleep 5
    echo "This is the script end..." >> test13b.out
    
    

    执行命令

    at -M -f test13b.sh now
    cat test13b.out
    
    

    3.列出等待的作业

    atq命令查看系统中有哪些作业在等待,显示作业列表
    作业列表中显示了作业号,系统运行该作业的日期和时间及其所在的作业队列

    4.删除作业

    命令格式:atrm 作业号
    命令说明:使用atrm删除指定作业

    16.6.2 安排需要定期执行的脚本

    1.cron时间表

    命令格式:min hour dayofmonth month dayofweek command
    命令说明:cron时间表采用一种特别的格式来指定作业何时运行

    格式说明

    dayofweek:文本(mon,tue,wed,thu,fri,sat,sun)或数值(0为周日,6为周六)
    dayofmonth:表示月份中的日期值(1~31)
    
    

    cron实例

    在每天的10:15运行一个命令
    15 10 * * * command
    在每周一4:15PM运行的命令
    15 16 * * 1 command
    在每个月的第一天中午12点执行命令
    00 12 1 * * command
    在每个月的最后一天执行命令
    00 12 * * * if [‘date +%d -d tomorrow’ = 01]; then;command
    说明:在每天中午12点检查是不是当月的最后一天,如果是,cron将会运行该命令
    
    

    执行命令

    15 10 * * * /home/zc/test/unit16/test4.sh > test4.out
    
    

    2.构建cron时间表

    Linux提供了 crontab来处理cron时间表,使用cron时间表来运行安排好的任务

    命令格式:crontab -l
    命令说明:使用crontab -l列出已有的cron时间表

    3.浏览cron目录

    如果创建的脚本对精确的执行时间要求不高,则可以使用预配置的cron脚本目录

    四个基本目录

    hourly:每小时执行
    daily:每天执行
    monthly:每月执行
    weekly:每周执行
    
    

    执行命令

    ls /etc/cron.*ly
    
    

    16.6.3 使用新shell启动脚本

    每次启动一个新shell时,bash shell都会运行$HOME/.bashrc文件

    验证

    在$HOME/.bashrc文件的最后加入:echo "I'm in a new shell"
    然后保存,关闭shell终端
    重新打开shell终端时,可以看见该提示语
    
    

    16.7 小结

    本章主要讲解了linux中的信号控制,以后台模式执行脚本,指定时间执行脚本,修改脚本的优先级等。

    谢谢

    相关文章

      网友评论

        本文标题:第二十八课 LinuxShell编程六之控制脚本

        本文链接:https://www.haomeiwen.com/subject/xqwawftx.html