关于进程的几点疑问,附实例

sh/bash/dash/ksh/zsh等Shell脚本
回复
糊涂的小强
帖子: 71
注册时间: 2014-04-28 14:33
系统: ubuntu12&centos6

关于进程的几点疑问,附实例

#1

帖子 糊涂的小强 » 2014-05-20 21:16

代码: 全选

#!/bin/bash
TIMELIMIT=3
PrintAnswer()
{
 if [ "$answer" = "TIMEOUT" ]
 then
   echo $answer
 else
  echo "Your favorite veggie is $answer"
  kill $!
  fi
}


TimerOn()
{
 sleep $TIMELIMIT && kill -s 14 $$ &
}

Int14Vector()
{
 answer="TIMEOUT"
 PrintAnswer
 exit 14
}

trap Int14Vector 14

echo "What is your favorite vegetable"
TimerOn
read answer
PrintAnswer
exit 0
首先谈谈我的理解: 首先 $!代表后台中运行的最后一个进程,$$代表该shell脚本
其次 kill $!就是在脚本运行到最后就把后台进程给杀掉,
但是下面的代码,之间是如何关联的呢, kill -s 14 $$如何解释呢,man kill还是不能理解为什么最后跟$$,另外trap Int14Vector 14意思是不是捕捉到sigal 14 就执行Int14Vector呢,shell又是如何释放signal 14呢。

代码: 全选

TimerOn()
{
 sleep $TIMELIMIT && kill -s 14 $$ &
}

Int14Vector()
{
 answer="TIMEOUT"
 PrintAnswer
 exit 14
}

trap Int14Vector 14
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 关于进程的几点疑问,附实例

#2

帖子 astolia » 2014-05-20 22:33

$$是当前shell的pid(不是子shell的pid)

# 如果收到14号信号就执行Int14Vector
trap Int14Vector 14
echo "What is your favorite vegetable"
# 在子shell进程中等待3秒后向父shell发送14号信号
sleep $TIMELIMIT && kill -s 14 $$ &
# 等待用户输入
read answer
# 如果在三秒内输入了内容,就直接显示
PrintAnswer

# 如果三秒内没有输入内容,父shell会收到14号信号,转去执行Int14Vector
Int14Vector()
{
answer="TIMEOUT"
PrintAnswer
exit 14
}

不知道你所说的“释放signal 14”是什么意思。如果信号被捕捉了,处理函数(即Int14Vector)执行完后会回到收到信号时的执行位置继续运行。但由于Int14Vector最后用了exit,所以父进程也就结束了。如果把exit一行删掉,父进程还会继续等待输入
cao627
帖子: 992
注册时间: 2007-12-05 10:57
系统: ubuntu14.04
来自: 金山

Re: 关于进程的几点疑问,附实例

#3

帖子 cao627 » 2014-05-20 22:47

trap Int14Vector 14 ########################## 设置让当前脚本捕获信号14,即如果脚本收到信号14,执行 Int14Vector 函数

echo "What is your favorite vegetable"

TimerOn ################################### 执行TimerOn函数,即执行sleep $TIMELIMIT && kill -s 14 $$ &,该函数会分配一个独立的进程号
read answer ################################如果三秒后还没有读取answer,函数TimeOn 中的kill -s 14 $$ 被执行到,即函数TimeOn发送一个信号14给当前脚本,trap捕获到信号14,于是 Int14Vector 函数被执行,answer="TIMEOUT",PrintAnswe的if分支被执行,最后exit 14。

PrintAnswer ################################如果3秒内读取到answer,PrintAnswe的else分支被执行,kill $!被执行,TimerOn函数就被 kill掉。
exit 0
糊涂的小强
帖子: 71
注册时间: 2014-04-28 14:33
系统: ubuntu12&centos6

Re: 关于进程的几点疑问,附实例

#4

帖子 糊涂的小强 » 2014-05-21 10:17

$$是当前shell的pid(不是子shell的pid)
在这个脚本中子进程或则说子shell应该是脚本中的每个命令,父进程(父shell)就是当前脚本shell,
那么你说的当前shell是指bash呢还是当前的脚本shell
# 在子shell进程中等待3秒后向父shell发送14号信号
sleep $TIMELIMIT && kill -s 14 $$ &
# 等待用户输入
read answer
# 如果在三秒内输入了内容,就直接显示
PrintAnswer
sleep $TIMELIMIT && kill -s 14 $$ &与read answer的执行顺序是如何控制的呢,前者sleep 3 秒然后后台执行signal14,后台不是不影响前台命令的执行吗,
但从测试看3秒后就立即执行了kill -s 14 $$,额我在哪看到说后台要等前台执行完了在执行。。。。。。
astolia 写了: 不知道你所说的“释放signal 14”是什么意思。如果信号被捕捉了,处理函数(即Int14Vector)执行完后会回到收到信号时的执行位置继续运行。但由于Int14Vector最后用了exit,所以父进程也就结束了。如果把exit一行删掉,父进程还会继续等待输入
我的意思是 这个signal 14是有谁send出的
上次由 糊涂的小强 在 2014-05-21 10:35,总共编辑 1 次。
糊涂的小强
帖子: 71
注册时间: 2014-04-28 14:33
系统: ubuntu12&centos6

Re: 关于进程的几点疑问,附实例

#5

帖子 糊涂的小强 » 2014-05-21 10:22

cao627 写了:trap Int14Vector 14 ########################## 设置让当前脚本捕获信号14,即如果脚本收到信号14,执行 Int14Vector 函数

echo "What is your favorite vegetable"

TimerOn ################################### 执行TimerOn函数,即执行sleep $TIMELIMIT && kill -s 14 $$ &,该函数会分配一个独立的进程号
read answer ################################如果三秒后还没有读取answer,函数TimeOn 中的kill -s 14 $$ 被执行到,即函数TimeOn发送一个信号14给当前脚本,trap捕获到信号14,于是 Int14Vector 函数被执行,answer="TIMEOUT",PrintAnswe的if分支被执行,最后exit 14。

PrintAnswer ################################如果3秒内读取到answer,PrintAnswe的else分支被执行,kill $!被执行,TimerOn函数就被 kill掉。
exit 0
signal14 是函数TimeOn发出的? kill -s 14就是发出signal14 ?偶,我以为这是捕获信号呢
糊涂的小强
帖子: 71
注册时间: 2014-04-28 14:33
系统: ubuntu12&centos6

Re: 关于进程的几点疑问,附实例

#6

帖子 糊涂的小强 » 2014-05-21 10:30

trap Int14Vector 14
这个命令在shell脚本退出执行前都处于,监听状态吗,因为我看他在几个执行函数最前面执行的
头像
astolia
论坛版主
帖子: 6703
注册时间: 2008-09-18 13:11

Re: 关于进程的几点疑问,附实例

#7

帖子 astolia » 2014-05-21 12:41

糊涂的小强 写了:在这个脚本中子进程或则说子shell应该是脚本中的每个命令,父进程(父shell)就是当前脚本shell,
那么你说的当前shell是指bash呢还是当前的脚本shell
你的概念有点混乱。shell通常都是指命令行解析器(比如bash、dash、csh、zsh之类)。所以只有在脚本中新创建了一个命令行解析器进程时才会称为子shell,执行一般命令虽然会新建个子进程,但不称为子shell。在你那个例子里面,只有用&后台执行的时候才会创建子shell。
由于脚本是在一个bash进程中解释执行的,所以“当前shell”和“当前的脚本shell”都是指bash进程
糊涂的小强 写了:sleep $TIMELIMIT && kill -s 14 $$ &与read answer的执行顺序是如何控制的呢,前者sleep 3 秒然后后台执行signal14,后台不是不影响前台命令的执行吗,
但从测试看3秒后就立即执行了kill -s 14 $$,额我在哪看到说后台要等前台执行完了在执行。。。。。。
这个顺序在你那段代码中是无法预测的,有可能sleep先,也有可能read先,看内核的进程调度了。总体而言,两个shell的执行是并行的
糊涂的小强 写了: 我的意思是 这个signal 14是有谁send出的
你说你man kill了,难道没看到它开宗明义第一段内容就是
kill - send a signal to a process
另外send一般都翻译为发送,释放是release。
回复