免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3307 | 回复: 9
打印 上一主题 下一主题

fork+exec+subshell [复制链接]

论坛徽章:
1
寅虎
日期:2013-08-22 20:18:39
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-05-03 12:31 |只看该作者 |倒序浏览
# a=1
# set -x
# (echo $a;grep $a file)
+ echo 1
1
+ grep 1 file
1111111111

个人理解:

1. 首先()会fork一个subshell,会完全继承父shell的变量,即使没有export
2. 之后subshell会再执行echo $a,由于echo是个内部命令,所以subshell不需要exec,直接执行输出
3. 然后subshell再继续执行grep $a file,由于grep是个外部命令,所以subshell再fork+exec出一个孙shell,由于exec会清除变量,所以grep孙shell应该是获取不到a变量的值
但是现在孙shell却得到了a变量的值,用ps查看也是可以看到grep是运行在孙shell里面的

root     12379  0.0  0.0  5380 1560 pts/11   Ss   09:04   0:00  |   \_ -bash
root     23627  0.0  0.0  5380  676 pts/11   S+   12:14   0:00  |   |   \_ -bash
root     23629  3.3  0.0  6352  740 pts/11   S+   12:14   0:00  |   |       \_ grep 1 file

参考了以下几篇贴子,希望有人能帮忙解释grep是怎么获取到a变量的值的,不甚感谢

http://bbs.chinaunix.net/viewthread.php?tid=1802783

http://bbs.chinaunix.net/viewthr ... p;extra=&page=1

http://bbs.chinaunix.net/viewthread.php?tid=1479880

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
2 [报告]
发表于 2011-05-03 13:17 |只看该作者
回复 1# ttxy624


    执行 echo $a;grep $a file 时,shell先进行处理,参数展开后,成为 grep 1 file,再什么 fork-exec,所以也“看到了“未export的变量。

论坛徽章:
1
寅虎
日期:2013-08-22 20:18:39
3 [报告]
发表于 2011-05-03 13:34 |只看该作者
回复 2# blackold


    http://bbs.chinaunix.net/viewthr ... p;extra=&page=1

这个贴子中,5楼的说明也是这个意思,但是您6楼的回贴说明,却是先执行再进行参数展开的,不知道是不是我理解错误?

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
4 [报告]
发表于 2011-05-03 13:43 |只看该作者
本帖最后由 blackold 于 2011-05-03 13:48 编辑

回复 3# ttxy624


    我的意思是开始执行时才展开,不是说先执行后展开。

  另外,原6楼的意思和我的意思不同吧:
(...$a...)
  我的意思是:
在子shell中执行时才展开$a,6楼的意思应该是先展开$a, 成(...a的值...),再在子shell中执行。

论坛徽章:
1
寅虎
日期:2013-08-22 20:18:39
5 [报告]
发表于 2011-05-03 14:05 |只看该作者
回复 4# blackold


    恩,大概明白了

# cat a.sh
#!/bin/sh
echo "$a"
grep "$a" file

# cat file
1111111111
aaaaaaaaaa
bbbbbbbbbb

(echo $a;grep $a file;./a.sh)
1
1111111111

1111111111
aaaaaaaaaa
bbbbbbbbbb

这条命令最后调用a.sh文件,也是先执行参数展开,然后再fork一个subshell,再针对脚本做参数展开,最后对脚本中的grep命令fork-exec的,对吧?那么对于管道来说也是先进行参数展开再进行fork的吗?

如果是这样的话,就可以解释为什么a.sh这个脚本获取不到父shell的变量,而命令行的外部命令却可以获取到父shell的变量了。

# (echo $a;grep $a file;a=$a ./a.sh)
1
1111111111
1
1111111111

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
6 [报告]
发表于 2011-05-03 16:07 |只看该作者
回复 5# ttxy624


   
也是先执行参数展开,然后再fork一个subshell,再针对脚本做参数展开



只展开一次。

你先搞清楚命令是如何执行的吧。

论坛徽章:
1
寅虎
日期:2013-08-22 20:18:39
7 [报告]
发表于 2011-05-06 12:12 |只看该作者
回复 6# blackold


        黑哥说话就是这么深奥   对于新手的我有点看不懂,找到了一篇命令行处理的文章

http://www.linuxsir.org/bbs/thread99465.html

反复看了2天,但还是不了解  # (echo $a;grep $a file;a=$a ./a.sh)  这个命令的展开为什么只有一次

我的理解:

       1. 因为是在()里面执行命令分组,首先fork一个子shell
       2. 在子shell中首先进行token分割,分割成3个字
       3. 然后针对第一个字进行处理、执行,然后输出变量a,因为echo是子shell本身的一部分,所以不需要fork和exec,而直接执行
       4. 再执行第2个字,查找$a,先对$a展开成1,然后fork+exec来执行grep
       5. 再针对第3个字执行展开,将a=$a开展成a=1,然后传递变量给./a.sh
       6. 执行a.sh时,先fork一个孙shell,然后在孙shell中执行echo和fork+exec来执grep,其中脚本中的$a也是需要展开的,所以最后一个命令我理解的是需要展开2次

整个命令执行中应该会产生4层shell吧?但是我用ps auxf只抓到3层,不知道是什么问题?

希望黑哥能有空能给详细解释一下,并非伸手党,一个人弄不明白,有个高手指点的话会事半功倍 。。。

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
8 [报告]
发表于 2011-05-06 18:34 |只看该作者
回复 7# ttxy624


    我的意思是fork之前只展开一次。

   后面的展开是程序本身的事,比如 a.sh调用b.sh,b.sh又调用c.sh,你说展开多少次?

   另:
2: split into得到不是3个字。
产生的子shell,未必ps到吧。

论坛徽章:
1
寅虎
日期:2013-08-22 20:18:39
9 [报告]
发表于 2011-05-06 18:45 |只看该作者
回复 8# blackold


    恩,第2步字分割应该是得到了4个字

另外最后是产生了4层shell吗?如果用ps看不到,我应该怎么证实结果呢?

论坛徽章:
5
2015年辞旧岁徽章
日期:2015-03-03 16:54:152015年迎新春徽章
日期:2015-03-04 09:50:282015年亚洲杯之朝鲜
日期:2015-03-13 22:47:33IT运维版块每日发帖之星
日期:2016-01-09 06:20:00IT运维版块每周发帖之星
日期:2016-03-07 16:27:44
10 [报告]
发表于 2011-05-06 18:53 |只看该作者
回复 9# ttxy624


    这要先搞清楚什么是subshell,在你给出的链接中有讨论。

如fork后,马上exec了,这个fork的shell能ps到吗?这个我也不知道。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP