Linux之进程管理(3)作业管理

发布时间:2019-07-05 09:51:46编辑:auto阅读(1720)


    Linux之进程管理(3)作业管理

    Linux的作业控制介绍:

    前台作业:通过终端启动,且启动后一直占据终端;

    后台作业:可通过终端启动,但启动后转入后台运行(释放终端);

    让进程作业运行在后台:

    1、对运行中的进程:使用Ctrl+z

    2、尚未启动的作业:COMMAND &  (在命令行的最后面加一个&符号)

    后台作业与终端关系的处理:

    后台作业虽然被送往后台允许,但其依然与终端相关;退出终端,将关闭后台作业。如果希望送往后台后,同时剥离与终端的关系。可以使用下面两种方法:

    1、# nohup  COMMADND &   

    注:命令后台运行并忽略所在进程组接收的HUB信号,但是会生成一个临时文件

    2、# screen;  COMMAND

    注:使用打开一个临时会话,这样即断电,下次还恢复到screen的当前状态

     

    查看所有后台作业命令:

    jobs 命令

    jobs命令例子:

    #/etc/下的所有shell脚步文件路径保存到临时文件中,并放入后台执行

    [root@localhost ~]# find /etc/ -name '*.sh' -exec echo {} > /tmp/tempfile.log \; &
    [1] 2859

    #查看当前后台作业

    [root@localhost ~]# jobs
    [1]+  Done                    find /etc/ -name '*.sh' -exec echo {} \; > /tmp/tempfile.log

    解析:其中1表示为作业号,及1号后天作业,而Done表示停止了状态,表示进程已经结束。

    #将当前系统下的所有文件路径保存到临时文件中,并放入后台执行

    [root@localhost ~]# find /  -exec echo {} > /tmp/tempfile.log \; &
    [1] 5481

    #查看当前后台作业

    [root@localhost ~]# jobs
    [1]+  Running                 find / -exec echo {} \; > /tmp/tempfile.log &

    解析:这里显示 Runing表示正在执行中,因为文件太多所以执行速度不如上面快,执行结束后,如果不再查看jobs,进程会自动清除,并退出当前作业列表。

     

    作业控制命令:fg  bg  kill

    fg # 将指定后台作业编号的进程调回前台运行;

    格式:fg #  或者 fg %#,如:fg 3   ,  fg  %3表示将后台3号作业放到前台

    bg # 让送往后台的作业在后台继续运行;

        格式:bg #  或者 bg %#,如:bg 10  , bg  %3表示将3号作业继续在后台运行

    kill %#  终止指定的作业;

    格式:kill %#,如:kill  %1  表示杀掉一号作业

     

    jobsfgbg等信号命令配合例子:

    #讲当前系统下的所有文件列表排序后输入到一个文件保存

    [root@mageedu ~]# du -a / | sort -rn > /tmp/du.sorted

    解析:因为有很多文件输出到一个文件,且当前控制台不会显示,所有,进程会一直等待输出重定向介绍,此时,按Ctrl+z键,将此命令放入后台:

    [root@mageedu ~]# du -a / | sort -rn > /tmp/du.sorted
     
    [1]+  Stopped                 du -a / | sort -rn > /tmp/du.sorted

    解析:这里现在是暂停状态,因此,需要再次唤醒。

    #查看当前的后台作业列表

    [root@mageedu ~]# jobs
    [1]+  Stopped                 du -a / | sort -rn > /tmp/du.sorted

    解析:这里发现了只有一个后台作业,也就是刚才执行的重定向命令。但是这里显示是Stoped暂停等待状态,因此此时进程虽然在后台,但是并没有开始运行。

    #调动1号作业在后台继续运行

    [root@mageedu ~]# bg 1
    [1]+ du -a / | sort -rn > /tmp/du.sorted &

    #再次查看当前jobs作业状态

    [root@mageedu ~]# jobs 
    [1]+  Running                 du -a / | sort -rn > /tmp/du.sorted &

    解析:这时已经表示在后台运行,此时可以执行其他操作,此作业执行完成后会自动退出进程并清除作业记录。

     

    让一个作业开始就在后台进行运行:

    #在要执行的命令最后面加入 &符号

    [root@mageedu ~]# du -a / | sort -rn > /tmp/du.sorted &
    [1] 28464

    # 查看当前作业列表

    [root@mageedu ~]# jobs
    [1]+  Running                 du -a / | sort -rn > /tmp/du.sorted &

    解析:这里因为把标准输出转向一个文件,所以不会印象当前进程中工作。但是如果执行的命令或者程序本身就会对当前终端有标准输出,那么即使在后台运行,也会把信息输入到当前控制台,因此就会影响当前终端会话。如:

    #执行ping命令并放入后台

    [root@mageedu ~]# ping 10.1.0.1 &

    wKioL1fVJNbAu_H0AAAwsaZr7SQ909.png 

    解析:这时会发现虽然能输入命令,但是ping的结果的标准输出还是会输出来,下面我通过画框标记来解释:

    第一个红色框:这里按这平时命令jobs

    第一个绿色框:此时下面显示了在运行状态,作业号为2

    第二个红色框:于是把2行作业调回前台。然后按Ctrl+c键发送INT信号;

    第一个紫色框:出现下面信息表示已经总结。

     

    通过以上发现在处理对当前终端有标准终端的进程作业,即使掉入到后台也不是很好的选择,因为会影响到当前终端界面的使用的查看。那么怎么处理这种问题?

    使用nodup命令,忽略接收进程组的INT信号:

    [root@mageedu ~]# nohup ping 10.1.0.1 &
    [1] 30344
    [root@mageedu ~]# nohup: appending output to `nohup.out'

    解析:这里出现了一个提示,表示会把输出的结果放入到nohup.out文件中,这样就代替了终端来接收标准输出。

    #查看当前作业,发现正在运行

    [root@mageedu ~]# jobs
    [1]+  Running                 nohup ping 10.1.0.1 &

    #使用kill命令终结此作业

    [root@mageedu ~]# kill -15 %1

    提示:后面的作业号必须要加上%,表示为jobs列表中的作业号,否则就当作进程的PID了。

     

    使用screen建立额外的会话窗口:

    #打开一个screen

    [root@mageedu ~]# screen

    #备份etc目录文件

    [root@mageedu ~]# find /etc -exec cp -a {} /tmp/etc-bak \;

    #此时按Ctrl+a,d来暂时剥离当前screen会话会显示当前session已经隔离

    [detached]

    #于是我们就可以执行其他工作了,等待备份完层后,再回到screen会话

    [root@mageedu ~]# screen

    #然后完全退出screen会话

    [root@mageedu ~]# exit



    额外例子(模拟并行多个进程):

    #创建3个文件

    [root@localhost ~]# ls ./*.sh
    ./all.sh  ./f1.sh  ./f2.sh  ./f3.sh

    #每个文件都只打印自己的文件基名

    [root@localhost ~]# cat f1.sh 
    #!/bin/bash
    #
      echo `basename $0`;

    #创建all.sh文件,内容如下

    [root@localhost ~]# cat all.sh 
    while :;do
    ./f1.sh&
    ./f2.sh&
    ./f3.sh&
    sleep 2
    done

    #给所有刚刚创建的文件加执行权限

    [root@localhost ~]# chmod +x ./*.sh

    #运行all.sh

    [root@localhost ~]# ./all.sh 
    f2.sh
    f3.sh
    f1.sh
    f2.sh
    f1.sh
    f3.sh
    f1.sh

    解析:我们发现当3个脚步同时在后台运行时,运行的队列是随机排放的,此时3个文件像是在同时运行,其实是在后台开启了3个子shell各种运行自己。

     

    #修改f{1,2,3}个文件,内容如下:

    [root@localhost ~]# cat f1.sh 
    #!/bin/bash
    #
    let i=0;
    while [ $i -lt 10 ];do
      echo `basename $0`;
      i=$[i+1];
      sleep 2
    done


    #在命令行中使用()阔住命令开启子shell进程后台运行

    [root@localhost ~]# (./f1.sh&);(./f2.sh&);(./f3.sh&)f1.sh
    f3.sh
    f2.sh
    f1.sh
    f3.sh
    f2.sh
    f1.sh
    f3.sh

    解析:这里同样是打开了3个子shell,并且都在后台运行,各种互不干扰。

     

    #下面杀死所有刚才执行脚步进程

    [root@localhost ~]# pkill '^f[0-9]\.sh'

    #使用{}阔起来

    [root@localhost ~]# { ./f1.sh& ./f2.sh& ./f3.sh& }
    f1.sh
    f3.sh
    f2.sh
    f1.sh
    f2.sh
    f3.sh
    f1.sh
    f2.sh
    f3.sh

    解析:这里是使用了bash里面的代码块机制,将多个执行语句使用{},当作一个块语句执行。


关键字