Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2043232
  • 博文数量: 470
  • 博客积分: 10206
  • 博客等级: 上将
  • 技术积分: 5620
  • 用 户 组: 普通用户
  • 注册时间: 2008-07-03 12:50
文章分类

全部博文(470)

文章存档

2012年(1)

2011年(18)

2010年(47)

2009年(404)

分类:

2009-06-15 10:03:34

[] [] [] [] []
版主   帅哥 (孩儿他爹㊞)
广告杀手-老法王



CU编号: 17255
注册:2002-8-26
最后登录: 2009-06-15
帖子:
精华:







来自:中国南京
状态:...在线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 09:14 

几个知识点
1.Bash在实现pipeline(管道|)时会发起两个subshell(子shell)来运行|两边的命令,对于系统来说就是发起两个childprocess(子进程)

2.fork是产生process的唯一途径,exec*是执行程序的唯一途径

3.子进程会完全复制父进程,除了$PID与$PPID

4.fork子进程时继承父进程的进程名,在exec*执行命令时才由exec*替换为子进程对应的命令,同一进程的命令名可以由一个个exec*任意多次的改变



[注]对于linux平台,JB上就是这样的,其它平台不好发表意见,当然对于2中的两个唯一有一个例外,就是在kenerl  init的初期;
暂时找不到相关参考,也没有功力读源码,所以此论是道听途说级别,错误之处请指出改正,如果没有改正的价值可一笑而过


[ 本帖最后由 waker 于 2006-4-7 09:17 编辑 ]



您对本贴的看法:

__________________________________

=GNU/linux=
GNU {bash 2.05b, grep 2.5, Awk 3.1.3, sed 4.0.8}

导师说:站起来吧
众人说:那么辛苦那么艰苦到底值不值?

设计师说:富起来吧
众人说:拼啦

| |
版主   帅哥 (孩儿他爹㊞)
广告杀手-老法王



CU编号: 17255
注册:2002-8-26
最后登录: 2009-06-15
帖子:
精华:







来自:中国南京
状态:...在线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 09:15 

问题的发生

当时的情况是:大家在讨论一个与进程统计的问题
%3D1
思考了一刻钟后我作了一个习惯性的决定:简化一下这个问题
下面的脚本 get_process

CODE:
#!/bin/bash
ps -ef|grep get_process

运行./get_process后会得到什么结果

结果有三种

CODE:
waker     3260  3193  0 08:47 pts/1    00:00:00 /bin/bash ./get_process



CODE:
waker     3290  3193  0 08:48 pts/1    00:00:00 /bin/bash ./get_process
waker     3292  3290  0 08:48 pts/1    00:00:00 /bin/bash ./get_process



CODE:
waker     3263  3193  0 08:48 pts/1    00:00:00 /bin/bash ./get_process
waker     3265  3263  0 08:48 pts/1    00:00:00 grep get_process

大家产生了种种解释
其实大家离真相只有0.01mm的距离
让我来提示一下
观察三种结果,都有一个共同的进程,就是PPID 是3193的 /bin/bash ./get_process
那么3193是什么
只要echo $$就可以看出3193就是我们键入 ./get_process的shell



您对本贴的看法:

__________________________________

=GNU/linux=
GNU {bash 2.05b, grep 2.5, Awk 3.1.3, sed 4.0.8}

导师说:站起来吧
众人说:那么辛苦那么艰苦到底值不值?

设计师说:富起来吧
众人说:拼啦

| |
版主   帅哥 (孩儿他爹㊞)
广告杀手-老法王



CU编号: 17255
注册:2002-8-26
最后登录: 2009-06-15
帖子:
精华:







来自:中国南京
状态:...在线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 09:15 

我的解释

让我们参照四个知识点来解释这个现象
首先当前shell 3193发起一个subshell来执行脚本./get_process
这个进程pid 3290 进程名 /bin/bash ./get_process
然后当它遇到管道,将发起两个子进程 3291(用来执行ps) 3192(用来执行grep),这两个进程是并行的
让我们给3192来个慢镜头

CODE:
           史前时代                   fork                                       exec*(grep.*)
pid          N/A                               3192
进程名       N/A        /bin/bash ./get_process                  grep get_process
说明         N/A       这个进程名继承自父进程                          exec*将进程名替换

而用3291中的ps来观察这个进程的时候,由于两个子进程的并行,每一种状态都可能被ps看到,当然每次只能看到一种状态
所以结果会有三种情况
进程3290(/bin/bash ./get_process)
与下面三种可能的组合
1.空
2.子进程3292 进程名 /bin/bash ./get_process
3.子进程3292 进程名 grep get_process

[ 本帖最后由 waker 于 2006-4-7 09:18 编辑 ]



您对本贴的看法:

__________________________________

=GNU/linux=
GNU {bash 2.05b, grep 2.5, Awk 3.1.3, sed 4.0.8}

导师说:站起来吧
众人说:那么辛苦那么艰苦到底值不值?

设计师说:富起来吧
众人说:拼啦

| |
版主   帅哥 (孩儿他爹㊞)
广告杀手-老法王



CU编号: 17255
注册:2002-8-26
最后登录: 2009-06-15
帖子:
精华:







来自:中国南京
状态:...在线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 09:20 

作业

1.如何避免发起不想要的subshell?
2.如果在kornshell中,这种情况会发生么?



您对本贴的看法:

__________________________________

=GNU/linux=
GNU {bash 2.05b, grep 2.5, Awk 3.1.3, sed 4.0.8}

导师说:站起来吧
众人说:那么辛苦那么艰苦到底值不值?

设计师说:富起来吧
众人说:拼啦

| |
  帅哥 (呆子)
荣誉版主-精灵使
3楼楼长


CU奥运火炬传递手2008
荣誉版主  
CU编号: 115226
注册:2003-11-27
最后登录: 2009-06-15
帖子:
精华:







状态:...离线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 10:49 

2.如果在kornshell中,这种情况会发生么?
依然会发生,除非管道中最后一个命令时内部命令。



您对本贴的看法:

__________________________________

世上有两种人
一种是痛苦的人   /\../\ ~..~
一种是快乐的猪    (@)  (@)
\~~~^..^  ^. .^~~~/
  (___(oo)   (oo)___)

| |
  帅哥 (frame)
风云使者



CU编号: 184181
注册:2004-9-17
最后登录: 2008-10-24
帖子:
精华:0







状态:...离线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 11:05 

1.如何避免发起不想要的subshell?
定义变量,虽然很笨但应该可以解决问题



您对本贴的看法:

__________________________________

刚刚从虚拟回到现实,渐渐进入状态。
| |
版主   帅哥 (孩儿他爹㊞)
广告杀手-老法王



CU编号: 17255
注册:2002-8-26
最后登录: 2009-06-15
帖子:
精华:







来自:中国南京
状态:...在线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 11:26 

to 7兄:
我在kornshell中测试的结果是永远都ps出两个进程
get_process与grep



您对本贴的看法:

__________________________________

=GNU/linux=
GNU {bash 2.05b, grep 2.5, Awk 3.1.3, sed 4.0.8}

导师说:站起来吧
众人说:那么辛苦那么艰苦到底值不值?

设计师说:富起来吧
众人说:拼啦

| |
  帅哥 (呆子)
荣誉版主-精灵使
3楼楼长


CU奥运火炬传递手2008
荣誉版主  
CU编号: 115226
注册:2003-11-27
最后登录: 2009-06-15
帖子:
精华:







状态:...离线...

[] [] [博客]


[] 顶部
发表于 2006-4-7 12:14 

我的回复就是指进程数没有区别,为什么总是出现grep,可能是概率问题,也可能是ksh的机理造成的永远都是grep。



您对本贴的看法:

__________________________________

世上有两种人
一种是痛苦的人   /\../\ ~..~
一种是快乐的猪    (@)  (@)
\~~~^..^  ^. .^~~~/
  (___(oo)   (oo)___)

| |
  帅哥
大天使




CU编号: 207236
注册:2004-12-13
最后登录: 2009-02-12
帖子:
精华:0







来自:天津
状态:...保密...

[] [] [博客]


[] 顶部
发表于 2006-11-20 10:36 

ksh下没看到
waker     3292  3290  0 08:48 pts/1    00:00:00 /bin/bash ./get_process
这个进程的原因大概是因为此进程的cmd被写成了ps -ef吧
由于shell脚本本身必然会fork process,就不必监控了,可以改成

CODE:
#!/bin/bash
ps -ef|grep -w ps

这样来看,应该更清楚。
在我的环境
FC6
bash(GNU bash, version 3.1.17(1)-release (i686-redhat-linux-gnu))
ksh(  version         sh (AT&T Labs Research) 1993-12-28 r)
下测试获得完全一样的结论



您对本贴的看法:

__________________________________

SUN E4500/SUN F4800/SUN V880
Solaris 8
KSH/NAWK/SED/VIM 6.3.3/perl 5.005_03
| |
  帅哥
精灵使



CU编号: 177152
注册:2004-8-15
最后登录: 2009-06-12
帖子:
精华:0







状态:...离线...

[] [] [博客]


[] 顶部
发表于 2008-9-12 18:58 



QUOTE:
原帖由 waker 于 2006-4-7 09:14 发表
几个知识点
1.Bash在实现pipeline(管道|)时会发起两个subshell(子shell)来运行|两边的命令,对于系统来说就是发起两个childprocess(子进程)

2.fork是产生process的唯一途径,exec*是执行程序的唯一途径

...

这第三条太武断了,除了PID和PPID外,还有好多不同



您对本贴的看法:
| |

» » »

阅读(953) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~