《学习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中则不是。
原文地址:https://www.cnblogs.com/yfceshi/p/7252237.html