2025年shell脚本学习七(作业控制)

shell脚本学习七(作业控制)命令执行过裎中按 Ctrl Z 快捷键 命令在后台处于暂停状态 进程 进程是一个程序对某个数据集的执行过程 是分配资源的基本单位 作业 作业是用户需要计算机完成的某项任务 是要求计算机所做工作的集合 作业的调度属于高级调度

大家好,我是讯享网,很高兴认识大家。

命令执行过裎中按 Ctrl+Z 快捷键,命令在后台处于暂停状态

进程: 

进程是一个程序对某个数据集的执行过程,是分配资源的基本单位。

 作业:

作业是用户需要计算机完成的某项任务,是要求计算机所做工作的集合

作业的调度属于高级调度,进程的调度属于低级调度

作业就是从外存放到内存的一个过程,它可以包含一个或多进程。

        进程和作业的概念也有区别。一个正在执行的进程称为一个作业,而且作业可以包含一个或多个进程,尤其是当使用了管道和重定向命令。例如“nroff -man ps.1|grep kill|more”这个作业就同时启动了三个进程。

        作业控制指的是控制正在运行的进程的行为。比如,用户可以挂起一个进程,等一会儿再继续执行该进程。shell将记录所有启动的进程情况,在每个进程过程中,用户可以任意地挂起进程或重新启动进程。作业控制是许多shell(包括bash和tcsh)的一个特性,使用户能在多个独立作业间进行切换。

       一般而言,进程与作业控制相关联时,才被称为作业。

 

       在大多数情况下,用户在同一时间只运行一个作业,即它们最后向shell键入的命令。但是使用作业控制,用户可以同时运行多个作业,并在需要时在这些作业间进行切换。这会有什么用途呢?例如,当用户编辑一个文本文件,并需要中止编辑做其他事情时,利用作业控制,用户可以让编辑器暂时挂起,返回shell提示符开始做其他的事情。其他事情做完以后,用户可以重新启动挂起的编辑器,返回到刚才中止的地方,就象用户从来没有离开编辑器一样。这只是一个例子,作业控制还有许多其他实际的用途。

 jobs:该命令用于查看当前终端后台运行的任务。

ps:该命令用于查看瞬间进程的动态

控制脚本:

 1、处理信号

      1.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.2  生成信号 

            ① 中断进程

           Ctrl+C组合键会生成SIGINT信号,并将其发送给当前在shell中运行的所有进程。可以运行一 条需要很长时间才能完成的命令,然后按下Ctrl+C组合键来测试它

           
讯享网

            Ctrl+C组合键会发送SIGINT信号,停止shell中当前运行的进程。sleep命令会使得shell暂停 指定的秒数,命令提示符直到计时器超时才会返回。在超时前按下Ctrl+C组合键,就可以提前终 止sleep命令。

            ②  暂停进程 

            Ctrl+Z组合键会生成一个SIGTSTP信号,停止shell中运行的任何进程。停止(stopping)进程跟终止(terminating)进程不同:停止进程会让程序继续保留在内存中,并能从上次停止的位置继续运行

              

           方括号中的数字是shell分配的作业号(job number)。shell将shell中运行的每个进程称为作业, 并为每个作业分配唯一的作业号。它会给第一个作业分配作业号1,第二个作业号2,以此类推。
           如果你的shell会话中有一个已停止的作业,在退出shell时,bash会提醒你

              

          用ps命令来查看已停止的作业      

          在S列中(进程状态),ps命令将已停止作业的状态为显示为T。这说明命令要么被跟踪,要么被停止了。

          如果在有已停止作业存在的情况下,你仍旧想退出shell,只要再输入一遍exit命令就行了。 shell会退出,终止已停止作业。或者,既然你已经知道了已停止作业的PID,就可以用kill命令 来发送一个SIGKILL信号来终止它

           

           在终止作业时,最开始你不会得到任何回应。但下次如果你做了能够产生shell提示符的操作 (比如按回车键),你就会看到一条消息,显示作业已经被终止了。每当shell产生一个提示符时, 它就会显示shell中状态发生改变的作业的状态。在你终止一个作业后,下次强制shell生成一个提示符时,shell会显示一条消息,说明作业在运行时被终止了。

          

         1.3  捕获信号 

           trap命令允许你来指定shell 脚本要监看并从shell中拦截的Linux信号。如果脚本收到了trap命令中列出的信号,该信号不再由shell处理,而是交由本地处理。 

           trap命令的格式是: 
                  trap commands signals   

          这里有个简单例子,展示了如何使用trap命令来忽略SIGINT信号,并控制脚本的行为

               

          本例中用到的trap命令会在每次检测到SIGINT信号时显示一行简单的文本消息。捕获这些信号会阻止用户用bash shell组合键Ctrl+C来停止程序

            正常运行:

                

           用户主动使用Ctrl - C 尝试中断进程:

               

           此例中,每次使用Ctrl+C组合键,脚本都会执行trap命令中指定的echo语句,而不是处理该信号并 允许shell停止该脚本

           1.4 捕获脚本退出

                除了在shell脚本中捕获信号,也可以在shell脚本退出时进行捕获。这是在shell完成任务时 执行命令的一种简便方法。 要捕获shell脚本的退出,只要在trap命令后加上EXIT信号就行

               

              

              当脚本运行到正常的退出位置时,捕获就被触发了,shell会执行在trap命令行指定的命令。 如果提前退出脚本,同样能够捕获到EXIT

          1.5 修改或移除捕获

               在脚本中的不同位置进行不同的捕获处理,只需重新使用带有新选项的trap命令即可

               

              修改了信号捕获之后,脚本处理信号的方式就会发生变化。但如果一个信号是在捕获被修改 前接收到的,那么脚本仍然会根据最初的trap命令进行处理

              

             移除捕获:

               只需要在trap命令与希望恢复默认行为的信号列表之间加上两个破折号就可以删除已设置好的捕获。

            

           

           ------------------------------------------------------------------------------------------------------------------------------------

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

          --------------------------------------------------------------------------------------------------------------------------------------

          移除信号捕获后,脚本按照默认行为来处理SIGINT信号,也就是终止脚本运行。但如果信 号是在捕获被移除前接收到的,那么脚本会按照原先trap命令中的设置进行处理       

2、以后台模式运行脚本

          2.1  后台运行脚本

               后台运行脚本 只用在运行命令上加上一个 & 符即可

               (  注意: 放入后台执行的命令不能与前台有交互,否则这个命令是不能在后台执行的 )

              

             当&符放到命令后时,它会将命令和bash shell分离开来,将命令作为系统中的一个独立的后 台进程运行。

             [1] 2884 

             方括号中的数字是shell分配给后台进程的作业号。下一个数是Linux系统分配给进程的进程 ID(PID)。Linux系统上运行的每个进程都必须有一个唯一的PID。

             一旦系统显示了这些内容,新的命令行界面提示符就出现了。你可以回到shell,而你所执行 的命令正在以后台模式安全的运行。这时,你可以在提示符输入新的命令

            这表明了作业的作业号以及作业状态(Done),还有用于启动作业的命令。

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

           (  即交互式界面仍然会显示  )

            

           

           你会注意到上面两个例子中,命令、脚本的输出与shell提示符混杂在了一起。 

          处理方法: 最好是将STDOUT和STDERR进行重定向,避免这种杂乱的输出

          

         在终端会话中使用后台进程时一定要小心。注意,在ps命令的输出中,每一个后台进程都和 终端会话(pts/0)终端联系在一起。如果终端会话退出,那么后台进程也会随之退出

       2.2  在非控制台下运行脚本

           用nohup命令来实现,即使退出了终端会话脚本也会一直以后台模式运行到结束

           原理就是:nohup命令运行了另外一个命令来阻断所有发送给该进程的SIGHUP信号。这将会在退出终端会话时阻止进程退出

          

         

          -------------------------------------------------------------------------------------------------------------------------------------------------------

       说明  如果使用nohup运行了另一个命令,该命令的输出会被追加到已有的nohup.out文件中。当 运行位于同一个目录中的多个命令时一定要当心,因为所有的输出都会被发送到同一个 nohup.out文件中,结果会让人摸不清头脑

          ------------------------------------------------------------------------------------------------------------------------------------------------------- 

         

         

      2.3 作业控制

           在本篇博客的前面部分,你已经得知如何使用组合键停止shell中正在运行的作业。在作业停止后, Linux系统会让你选择是终止还是重启。你可以用kill命令终止该进程。要重启停止的进程需要 向其发送一个SIGCONT信号。 

         启动、停止、终止以及恢复作业的这些功能统称为作业控制。通过作业控制,就能完全控制 shell环境中所有进程的运行方式了。本节将介绍用于查看和控制在shell中运行的作业的命令。 

         2.3.1 查看作业

            作业控制中的关键命令是jobs命令。jobs命令允许查看shell当前正在处理的作业。 

        

           

           第二次使用同样的脚本,利用&将另外一个作业作为后台进程启动。出于简化的目的,脚本的输出被重定向到文件中,避免出现在屏幕上。( 此处如果不使用 > 重定向,即使将其放入后台,仍会与前台有互动产生输出 )

           jobs命令可以查看分配给shell的作业。jobs命令会显示这两个已停止/运行中的作业,以及它们的作业号和作业中使用的命令。 

          查看作业的PID,可以在jobs命令中加入 -l 选项

       -------------------------------------------------------------------------------------------------------------------------------------------------------

                                          jobs命令参数

                           参  数                                           描  述
                              -l                              列出进程的PID以及作业号

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

                              -p                             只列出作业的PID

                              -r                              只列出运行中的作业

                              -s                              只列出已停止的作业 

        -------------------------------------------------------------------------------------------------------------------------------------------------------

        下面例子说明了队列中的下一个作业在默认作业移除时是如何成为默认作业的。有3个独立 的进程在后台被启动。jobs命令显示出了这些进程、进程的PID及其状态。注意,默认进程(带 有加号的那个)是最后启动的那个进程,也就是3号作业。 
        

       调用kill命令向默认进程发送了一个SIGHUP信号,终止了该作业。在接下来的jobs 命令输出中,先前带有减号的作业成了现在的默认作业,减号也变成了加号。

     2.3.2  重启停止的作业

         在bash作业控制中,可以将已停止的作业作为后台进程或前台进程重启。前台进程会接管你当前工作的终端( 交互式进程会占用终端 ),所以在使用该功能时要小心了。

        要以后台模式重启一个作业,可用 bg命令加上作业号。

         

         bg命令将作业置于后台模式。注意,当使用了jobs命令时,它列出了作业及其状态,即便是默认作业当前并未处于后台模式   (由上图可以看出,使用bg命令之后脚本运行是紧接着以上开始,而不是从头开始运行)

         要以前台模式重启作业,可用带有作业号的 fg 命令。

      2.4  调整谦让度

         在多任务操作系统中(Linux就是),内核负责将CPU时间分配给系统上运行的每个进程。调 度优先级(scheduling priority)是内核分配给进程的CPU时间(相对于其他进程)。在Linux系统 中,由shell启动的所有进程的调度优先级默认都是相同的。 调度优先级是个整数值,从-20(最高优先级)到+19(最低优先级)。默认情况下,bash shell 以优先级0来启动所有进程。

      -------------------------------------------------------------------------------------------------------------------------------------------------------

       窍门 最低值-20是最高优先级,而最高值19是最低优先级,这太容易记混了。只要记住那句俗 语“好人难做”就行了。越是“好”或高的值,获得CPU时间的机会越低。

       -------------------------------------------------------------------------------------------------------------------------------------------------------

       2.4.1  nice命令 ( 用作升高NI值,即降低优先级 )( 只有一个选项-n )

          nice命令允许设置命令启动时的调度优先级。要让命令以更低的优先级运行,只要用nice 的-n命令行来指定新的优先级级别。 

          UID是用户ID,PID是进程ID,PPID是父进程ID

         

         注意,必须将nice命令和要启动的命令放在同一行中。ps命令的输出验证了谦让度值(NI 列)已经被调整到了10

         nice命令也可以直接在破折号跟优先级值,例如  nice  -10   ……

       2.5.2  renice命令

           renice允许通过运行进程的PID来改变它的优先级,nice是通过进程名

           

           renice命令会自动更新当前运行进程的调度优先级。

          和nice命令一样,renice命令也有一 些限制:

                只能对属于用户本身的进程执行renice;

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

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

         如果想完全控制运行进程,必须以root账户身份登录或使用sudo命令。 

       2.6  定时运行作业

         2.6.1  用at 命令来计划执行作业 ( 只会执行一次 )

              at命令允许指定Linux系统何时运行脚本。at命令会将作业提交到队列中,指定shell何时运 行该作业。at的守护进程atd会以后台模式运行,检查作业队列来运行作业。大多数Linux发行 版会在启动时运行此守护进程。

              atd守护进程会检查系统上的一个特殊目录(通常位于/var/spool/at)来获取用at命令提交的作业。默认情况下,atd守护进程会每60秒检查一下这个目录。有作业时,atd守护进程会检查 作业设置运行的时间。如果时间跟当前时间匹配,atd守护进程就会运行此作业

             1. at命令的格式

选项:    -m     当计划任务结束后发送邮件给用户

              -l        查看用户计划任务

               -d  (跟任务编号) 删除用户计划任务

               -c       查看at任务具体内容

            

           

             默认情况下,at命令会将STDIN的输入放到队列中。你可以用-f参数来指定用于读取命令(脚本文件)的文件名。

             time参数指定了Linux系统何时运行该作业。如果你指定的时间已经错过,at命令会在第二天的那个时间运行指定的作业。

            在如何指定时间这个问题上,非常灵活。at命令能识别多种不同的时间格式。

                  标准的小时和分钟格式,比如10:15。

                  AM/PM指示符,比如10:15 PM。

                  特定可命名时间,比如now、noon、midnight或者teatime(4 PM)。

                 除了指定运行作业的时间,也可以通过不同的日期格式指定特定的日期。

                  标准日期格式,比如MMDDYY、MM/DD/YY或DD.MM.YY。

                  文本日期,比如Jul 4或Dec 25,加不加年份均可。

                  你也可以指定时间增量。

                            当前时间+25 min

                            明天10:15 PM

                            10:15+7天

              在你使用at命令时,该作业会被提交到作业队列(job queue)。作业队列会保存通过at命令 提交的待处理的作业。针对不同优先级,存在26种不同的作业队列。作业队列通常用小写字母a~z 和大写字母A~Z来指代。 

           -------------------------------------------------------------------------------------------------------------------------------------------------------

          作业队列的字母排序越高,作业运行的优先级就越低(更高的nice值)。默认情况下,at的作业会被提交到a作业队列。如果想以更高优先级运行作业,可以用-q参数指定不同的队列字母

          --------------------------------------------------------------------------------------------------------------------------------------------------------

             2. 获取作业的输出

                 at命令利用sendmail应用程序来发送邮件。如 果你的系统中没有安装sendmail,那就无法获得任何输出!因此在使用at命令时,最好在脚本 中对STDOUT和STDERR进行重定向

                -M 可以屏蔽作业产生的输出信息

             3.列出等待的作业

                 atq命令可以查看系统中有哪些作业在等待( 第一列排序越高优先级越低 )

                 

             4.  删除作业

                  一旦知道了哪些作业在作业队列中等待,就能用atrm命令来删除等待中的作业

                  

          2.7安排需要定期执行的脚本( 周期执行 )

                   Linux系统使用cron程序来安排要定期执行的作业。cron程序会在后台运行并检查一个特殊的 表(被称作cron时间表),以获知已安排执行的作业。 

          2.7.1 使用cron制定计划任务之前需要确保crond服务是开启的,否则计划任务不会被执行

            

用法:    crontab  [-u 用户] [-l | -r | -e ]

选项:       -u            指定计划任务的用户,默认为当前用户

               -l             查看计划任务

               -r            删除计划任务

               -e            编辑计划任务

               -i             使用-r删除计划任务时要求用户确认删除

     

           例:(cron文件的编辑器是vim)

                $crontab  -e

                 

--------------------------------------------------------------------------------------------------------------------------------------------------------------

说明

      如何设置一个在每个月的最后一天执行的命令呢?因为你无法设置 dayofmonth的值来涵盖所有的月份。这个问题困扰着Linux和Unix程序员,也激发了不少解 决办法。常用的方法是加一条使用date命令的if-then语句来检查明天的日期是不是01:
     00 12 * * * if [`date +%d -d tomorrow` = 01 ] ; then ; command  

      它会在每天中午12点来检查是不是当月的最后一天,如果是,cron将会运行该命令。 

--------------------------------------------------------------------------------------------------------------------------------------------------------------

       

           cron程序会用提交作业的用户账户运行该脚本。因此,你必须有访问该命令和命令中指定的 输出文件的权限。

         2.7.2  构建cron时间表 

             每个系统用户(包括root用户)都可以用自己的cron时间表来运行安排好的任务。Linux提供 了crontab命令来处理cron时间表。要列出已有的cron时间表,可以用-l选项。 

           默认情况下,用户的cron时间表文件并不存在。要为cron时间表添加条目,可以用 -e 选项。 在添加条目时,crontab命令会启用文本编辑器vim,使用已有的cron时间表作为文件内容(或者是一个空文件,如果时间表不存在的话)。  

         2.7.3  浏览cron目录

           如果你创建的脚本对精确的执行时间要求不高,用预配置的cron脚本目录会更方便。有4个基本目录:hourly、daily、monthly和weekly

             

           因此,如果脚本需要每天运行一次,只要将脚本复制到daily目录,cron就会每天执行它。 

         2.7.4  anacron程序

              cron程序的唯一问题是它假定Linux系统是7×24小时运行的。除非将Linux当成服务器环境来 运行,否则此假设未必成立。

            如果某个作业在cron时间表中安排运行的时间已到,但这时候Linux系统处于关机状态,那么 这个作业就不会被运行。当系统开机时,cron程序不会再去运行那些错过的作业。要解决这个问 题,许多Linux发行版还包含了anacron程序。

           如果anacron知道某个作业错过了执行时间,它会尽快运行该作业。这意味着如果Linux系统 关机了几天,当它再次开机时,原定在关机期间运行的作业会自动运行。

          这个功能常用于进行常规日志维护的脚本。如果系统在脚本应该运行的时间刚好关机, 日志文件就不会被整理,可能会变很大。通过anacron,至少可以保证系统每次启动时整理日志文件。

          anacron程序只会处理位于cron目录的程序,比如/etc/cron.monthly。它用时间戳来决定作业 是否在正确的计划间隔内运行了。每个cron目录都有个时间戳文件,该文件位于/var/spool/ anacron

                  

           anacron程序使用自己的时间表(通常位于/etc/anacrontab)来检查作业目录                                                                                

               period条目定义了作业多久运行一次,以天为单位。anacron程序用此条目来检查作业的时间 戳文件。delay条目会指定系统启动后anacron程序需要等待多少分钟再开始运行错过的脚本。 command条目包含了run-parts程序和一个cron脚本目录名。run-parts程序负责运行目录中传给它的 任何脚本。

             注意,anacron不会运行位于/etc/cron.hourly的脚本。

               这是因为anacron程序不会处理执行时间 需求小于一天的脚本。

               identifier条目是一种特别的非空字符串,如cron-weekly。它用于唯一标识日志消息和错误 邮件中的作业。 

    

 

小讯
上一篇 2025-02-27 17:49
下一篇 2025-02-23 16:53

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/26074.html