zoukankan      html  css  js  c++  java
  • 《学习bash》笔记--进程处理

    1.进程ID和作业编号

     当通过附加&号后执行命令时。shell会响应例如以下:

    $ ls &
    [1] 3318
    当中[1]是作业号,3318是进程号。
    一个后台进程完毕时。shell会给出作业编号信息。例如以下:
    [1]+  Done                    ls --color=auto
    假设作业以非0状态退出时,shell指出其退出状态。

    2.作业控制

    作业编号能够使它们在shell命令中进行作业控制。

    一旦作业在后台执行,你能够让它一直执行,或把它放到前台,或向其发送信号。


    2.1.前台和后台

    内置fg命令将后台作业放到前台。使用不带參数的fg。shell会把后台作业放到前台,假设有多个作业在后台,shell会挑出最新在后台
    执行作业放到前台。假设想要将其它作业放到前台,须要给出前面加上百分号%的作业命令,或者使用作业编号前面加百分号%,也
    能够是不带百分号的进程ID。能够使用命令jobs列出后台作业。
    比如:
    yanwenjie@ywjpc:~/ctest$ ./a &
    [1] 3481
    yanwenjie@ywjpc:~/ctest$ ./b &
    [2] 3482
    yanwenjie@ywjpc:~/ctest$ ./c &
    [3] 3483
    yanwenjie@ywjpc:~/ctest$ jobs
    [1]   Running                 ./a &
    [2]-  Running                 ./b &
    [3]+  Running                 ./c &
    -p选项仅仅列出进程号:
    $ jobs -p
    3481
    3482
    3483
    假设键入fg。会把c放到前台。由于它是最新在后台执行的作业。
    假设键入fg %b,或者fg %2,b会进入前台。
    还能够通过%+引用被放到后台的最新作业,通过%-引用下一个近期被放到后台的作业。这边是b。


    以下列出了引用后台作业的几种方式:
    %N   作业编号N
    %string  其命令以string開始的作业
    %?string  其命令包括string的作业
    %+ 近期被调用的后台作业
    %%  同上
    %-  第二个近期被调用的后台程序

    2.2.挂起一个作业

    要挂起一个作业,在其执行时键入ctrl-z就可以。shell会对应例如以下消息:
    $ ./a
    ^Z
    [1]+  Stopped                 ./a
    然后返回shell提示符,要恢复一个挂机的作业使其继续在前台运行,键入fg就可以。假设有多个挂起的作业。能够使用带有一个作
    业名或者编号的fg。


    yanwenjie@ywjpc:~/ctest$ jobs
    [1]   Stopped                 ./a
    [2]-  Stopped                 ./b
    [3]+  Stopped                 ./c
    yanwenjie@ywjpc:~/ctest$ fg %1
    ./a
    假设键入ctrl-z后跟bg。就会把该作业放到后台执行。


    yanwenjie@ywjpc:~/ctest$ jobs
    [1]   Stopped                 ./a
    [2]-  Stopped                 ./b
    [3]+  Stopped                 ./c
    yanwenjie@ywjpc:~/ctest$ bg %2
    [2]- ./b &
    yanwenjie@ywjpc:~/ctest$ jobs
    [1]-  Stopped                 ./a
    [2]   Running                 ./b &
    [3]+  Stopped                 ./c

    3.信号

    3.1.控制键信号

    键入ctrl-c时,shell发送INT信号给当前作业,键入ctrl-z时。shell则发送TSTP。也能够向当前作业发送一个QUIT信号,方法是键入
    ctrl-。
    能够使用stty命令选项定制发送信号的控制键。这一点随系统的不同而变化,通常的语法是:stty signame char。signame时信号
    名,char是控制字符。可通过使用^符号表示控制后跟控制字符给出。比如,要将INT键设置为大多数系统上的ctrl-x,可使用:
    stty intr ^x。

    3.2.kill

    能够使用内置shell命令kill向你创建的不论什么进程发送一个信号。kill的參数为进程ID,作业编号。

    默认情况下,kill发送TERM信号,其效果与使用ctrl-c发送的INT信号一样。

    以下是kill的样例。这里有一个a进程,进程号是2680。作业号时1。開始能够使用例如以下命令:
    # ./a &
    [1] 2680

    # kill %1

    [1]+  Terminated              ./a

    假设没有看到该消息,TERM信号中断作业失败。下一步再试试QUIT:

    kill -QUIT %1

    假设工作正常会看到:

    [1]+  Quit                    (core dumped) ./a

    假设QUIT也不正常执行,自后一种方式是使用KILL:

    # kill -KILL %1

    [1]+  Killed                  ./a


    3.3.trap


    trap内置命令使你能够设置为捕获特定信号并以自己的方式处理它们。trap内置命令使你能够在一个shell脚本中完毕此功能。
    trap的语法是:
    trap cmd sig1 sig2 ...
    意思是 sig1,sig2等被接收时,运行cmd。然后恢复运行,cmd完毕后。脚本在被打断的命令后恢复运行。cmd能够为脚本或者
    函数。sigs可用名称或数字指定。

    比如:
    trap "echo 'you hit ctrl-c'" INT
    while true; do
    sleep 60
    done
    运行:
    # ./a.sh 
    ^Cyou hit ctrl-c
    ^Cyou hit ctrl-c
    按下ctrl-c后,脚本不会停止执行,而是sleep命令退出。脚本会循环回来启动还有一个sleep。

    3.4.进程ID变量

    $$是一个特殊shell变量。取值为当前shell的进程ID。

    比如例如以下脚本:
    echo $$
    while true; do
    sleep 10
    done
    运行结果:
    root@ywjpc:/home/yanwenjie/bashtest# ./a.sh &
    [1] 3258
    root@ywjpc:/home/yanwenjie/bashtest# 3258

    3.5.重置陷阱信号

    还有一个trap命令的特例发生在将短划线指定为命令參数时。

    它会将收到信号时的行为重置为默认欣慰,一般是进程的终止。

    比如a.sh例如以下所看到的:
    $ cat a.sh 
    trap "echo 'ctrl c is received'" INT
    i=5
    while [ $i -gt 0 ]; do
    sleep 5
    i=$((i-1))
    done
    trap - INT
    i=5
    while [ $i -gt 0 ]; do
            sleep 5
            i=$((i-1))
    done
    运行脚本:
    $ ./a.sh 
    ^Cctrl c is received
    ^Cctrl c is received
    ^Cctrl c is received
    ^Cctrl c is received
    ^Cctrl c is received
    ^C

    4.协同程序

    比如以下的脚本:
    alice &
    hatter
    此时hatter时脚本中最后一个命令,上述代码仅仅有当alice首先完毕时,才干工作正常。

    假设当脚本完毕时,alice仍然执行,那么

    它就变成孤儿。
    有一种方法能够确保alice完毕前脚本不会完毕:内置命令wait。不带參数时,wait指示等待,直至全部后台作业完毕,因此要确保
    上述代码工作正常。增加wait例如以下:
    alice &
    hatter
    wait
    这里。假设hatter先完毕, 父shell在结束自己前会等待alice完毕。


    5.子shell

    5.1.子shell继承

    关于子shell最关键的一点是它们从其父shell获得或继承了例如以下特性:
    • 当前文件夹
    • 环境变量
    • 标准输入,标准输出和标准错误,以及其他不论什么打开的文件描写叙述符。

    • 被忽略的信号。
    子shell未从其父shell继承的内容例如以下:
    • shell变量
    • 没有被忽略的信号处理

    5.2.嵌套子shell

    子shell不须要放在单独的脚本中,你也能够在与父shell同样的脚本中启动子shell。能够把某些shell代码放到圆括号里。则该代码
    将执行在子shell。我们称之为嵌套子shell。比如:
    ( while read line; do
        echo $line
    done
    ) | dc
    圆括号内代码会执行为一个单独的进程。

    这通常不如一个命令块效率高。子shell和命令块在功能上的区别非常少。它们之间的主要区别

    是作用域;亦即在该范围内一些定义是已知的。如shell变量和信号陷阱。

    首先,嵌套子shell内的代码服从上述子shell继承规则,除此

    之外还直到外部shell中定义的变量,块能够看做继承了外部shell的一切内容的代码单元。第二。一个命令块中定义的变量和信号陷阱
    对块后的shell代码时已知的,而在子shell中则不是。
  • 相关阅读:
    代码查错1
    代码查错
    垃圾回收器
    面试题(操作语句)
    面试题(JVM加载机制)
    面试题(线程)
    异常
    IO流
    es5 学习笔记
    ECMAScript5 Object的新属性方法
  • 原文地址:https://www.cnblogs.com/yfceshi/p/7252237.html
Copyright © 2011-2022 走看看