shell基础06 控制脚本

1. 处理信号

     Linux利用信号与运行在系统中的进程进行通信。


         信号                                        值                                             描述

          1                                            SIGHUP                                   挂起进程

          2                                            SIGINT                                     终止进程

          3                                            SIGQUIT                                  停止进程

          9                                            SIGKILL                                   无条件终止进程

         15                                           SIGTERM                                尽可能终止进程

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

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

         19                                           SIGCONT                                 继续运行停止的进程


         默认情况下,bash shell会忽略收到的任何SIGQUIT(3)和SIGTERM(15)信号(正因为这样,交互式shell才不会被意外终止)。但是bash shell会处理收到的SIGHUP(1)和SIGINT(2)信号。

         如果bash shell收到了SIGHUP信号,比如当你要离开一个交互式shell,它就会退出。但在退出之前,它会将SIGHUP信号传给所有由该shell所启动的进程(包括正在运行的shell脚本)。

         通过SIGINT信号,可以中断shell。Linux内核会停止为shell分配CPU处理时间。这种情况发生时,shell会将SIGINT信号传给所有由它所启动的进程,以此告知出现的状况。

         可以知道,shell会将这些信号传给shell脚本程序来处理。而shell脚本的默认行为是忽略这些信号。它们可能会不利于脚本的运行。要避免这种情况,你可以脚本中加入识别信号的代码,并执行命令来处理信号。

(1)生成信号

         ctrl+c 会产生SIGINT信号,完全中断进程

         ctrl+z 会残生SIGTSTP信号,停止进程,但是没有中断,可以通过kill命令来中断进程。使用kill必须带信号号数,比如:kill -9 2456    pid为2456的进程就中断了。

(2)捕获信号

         也可以不忽略信号,在信号出现时捕获它们并执行其它命令。trap命令允许你来指定shell脚本要监看并从shell中拦截的Linux信号。如果脚本收到了trap命令中列出的信号,该信号不再由shell处理,而是交由本地处理。

         trap commands signals

 1 trap "echo 'sorry,I have trapped ctrl_c'" SIGINT
 2 sleep 5
 3 echo "hahah"
 4 sleep 3
 5 echo "hello"
 6 [Hermioner@localhost Documents]$ bash test
 7 ^Csorry,I have trapped ctrl_c   #在sleep时按住了ctrl+c,这就发送了SIGINT信号
 8 hahah
 9 ^Csorry,I have trapped ctrl_c   #在sleep时按住了ctrl+c,这就发送了SIGINT信号
10 hello
11 [Hermioner@localhost Documents]$ 
View Code

 (3)移除捕获

         trap -- signals

 1 [Hermioner@localhost Documents]$ cat test
 2 #!/bin/bash
 3 trap "echo 'sorry,I have trapped ctrl_c'" SIGINT
 4 sleep 5
 5 echo "hahah"
 6 trap -- SIGINT
 7 sleep 3
 8 echo "hello"
 9 [Hermioner@localhost Documents]$ bash test
10 ^Csorry,I have trapped ctrl_c
11 hahah
12 ^C
13 [Hermioner@localhost Documents]$ 
View Code

2. 以后台模式运行脚本-----随着会话的结束而结束

      在后台模式中,进程运行时不会和终端会话上的STDIN、STDOUT以及STDERR关联。允许它们在后台运行而不用占用终端会话,这样就可以在终端上做别的事情啦。

      直接加入&就可以以后台模式运行shell脚本啦。

 1 [Hermioner@localhost Documents]$ cat test
 2 #!/bin/bash
 3 sleep 3
 4 echo "hello"
 5 [Hermioner@localhost Documents]$ bash test &
 6 [1] 4878
 7 [Hermioner@localhost Documents]$ ls
 8 a      ltest  test1     test2     test3     test8  testfile
 9 atest  test   test1.sh  test2.sh  test3.sh  test9
10 [Hermioner@localhost Documents]$ hello
11 ^C
12 [1]+  Done                    bash test
13 [Hermioner@localhost Documents]$ 
14 
15 
16 在休眠时候,可以执行别的语句。当后台执行完毕,会自动输出到终端上面来,hello,并且需要按住ctrl+c才终止。
View Code

      note1:可以在命令提示符下同时启动多个后台作业

      note2:一旦会话退出,那么后台进程也会随之退出。

3. 在非控制台下运行脚本-------后台进程不会因为会话的结束而结束

       采用nohup命令可以实现,它运行了另外一个命令来阻断所有发送给该进程的SIGHUP信号,这回在退出终端会话时阻止进程退出。

       nohup ./test1.sh &

       note1:由于nohup命令会解除终端与进程的关联,进程也就不再同STDOUT和STDERR联系在一起。为了保存该命令产生的输出,nohup命令会自动将STDOUT和STDERR的消息重定向到一个名为nohup.out的文件中。

 4. 作业控制

      启动、停止、终止以及恢复作业的这些功能称为作业控制。通过作业控制,就能完全控制shell环境中所有的进程的运行方式了。

     (1)查看作业

               jobs命令。允许查看当前正在处理的作业。

               eg:   $    jobs

                       [1]    Running       ./test9.sh

                       [1] + Stopped      ./test10.sh

                       [2] -  Running      ./test10.sh > test10.out &

                note:jobs命令输出中的加号和减号。带加号的作业会被当作默认作业。带减号的作业是下一个默认作业。任何时候都只有一个带加号和带减号的作业,不管          由多少个shell正在运行。

       (2)重启停止的作业

                 可以将已经停止的作业作为后台进程或前台进程重启。后台用     bg 作业号         前台用    fg 作业号

 5. 调整谦让度

      在多任务操作系统中(Linux就是),内核负责将CPU时间分配给系统上运行的每个进程。调度优先级是内核分配给进程的CUP时间(相对于其它进程)。在Linux系统中,由shell启动的所有进程的调度优先级默认都是相同的。

      调度优先级是个整数值,从-20(最高优先级)到+19(最低优先级)。默认情况下,bash shell以优先级0来启动所有进程。

       nice -n 具体的数值  启动命令     eg:  nice -n 4  ./test.sh

       note:无法提高命令的优先级,只可以减小。

       note2: renice命令也可以降低优先级,但是它可以更改已经运行的命令的优先级,它能够自动更新当前运行进程的调度的优先级。

6.  定时运行作业

     可以采用at命令和cron表来定时运行作业。

     (1)at

              原理:at命令允许指定Linux系统何时运行脚本。at命令会将作业提交到队列中,指定shell何时运行该作业。at的守护进程atd会以后台模式运行,检查作                   业队列来运行作业。大多数Linux发行版会在启动时运行此守护进程。atd守护进程会检查系统上的一个特殊目录(通常位于/var/spool/at)来获取at命令提交                   的 作业。默认情况下,atd守护进程会每60秒检查一下这个目录。有作业时,atd守护进程会检查作业设置运行的时间。如果时间跟当前时间匹配,atd守护进                 程就会运行此作业。 如果你指定的时间已经错误,at命令会在第二天的那个时候运行指定的作业。

       格式:   at  [ -f  filename]  time

              默认情况下,at命令会将STDIN的输入放到队列中。也可以添加-f参数来指定用于读取命令(脚本文件)的文件名。time的时间格式也支持很多种。

        eg:  at -f  test12.sh  now

        缺点:at命令会自动使用sendmail应用程序来发送邮件,在邮件中的内容就是STDOUT和STDERR内容。因此还需要安装sendmail软件。因此,为避免,可以在脚 本中采用输出重定向,这样就不通过邮件将echo等语句输出放到邮件中了。也可以删除队列中等待的的作业。

      (2) cron时间表

                如果要脚本在每天的同一时间运行,或者每周一次等等,就不能使用at不断提交作业了,可以采用cron程序来安排要定期执行的作业。

           格式:   min hour dayofmonth month dayofweek command

            eg: 15 10 * * * command  表面会在每个月每天的10:15执行该命令。

            缺点,可能服务器关机了,停机的那些天的命令在开机后不会执行。为避免这个,可以采用anacron程序来执行之前因为关机未执行的程序。---------运维用的。

参考文献

Linux命令行与shell脚本编程大全(第3版)[美] 布鲁姆Richard Blum),布雷斯纳汉Christine Bresnahan) 著,门佳武海峰 译

猜你喜欢

转载自www.cnblogs.com/Hermioner/p/9384816.html