免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 18518 | 回复: 67

关于subshell和child process的问题 [复制链接]

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-01-24 06:20:00
发表于 2009-07-22 14:37 |显示全部楼层
一直以为subshell和child process是一回事情,突然发现完全不是我想的那么一回事

做了下面这样一个测试:

[oracle@Minerva practice]$ cat a
a=1;echo $$
echo ----------
(echo $a;echo $$)
[oracle@Minerva practice]$ a
21661
----------
1
21661
[oracle@Minerva practice]$ cat b
echo $a;echo $$
[oracle@Minerva practice]$ sed -i '3s/.*/b/' a
[oracle@Minerva practice]$ cat a
a=1;echo $$
echo ----------
b
[oracle@Minerva practice]$ a
21667
----------

21669
[oracle@Minerva practice]$


subshell根本不像我以前想象的一样是个child process,它并不像后者一样fork出了一个新的process,但为什么我们管它叫subshell?subshell能够继承parent shell(不知道这么描述正确吗?)未被export的变量,但是child process不行;它们相同的地方就在于子shell或者子进程里的变量无法影响其父shell或者父进程?

是不是我哪里理解错了?

论坛徽章:
0
发表于 2009-07-22 14:49 |显示全部楼层

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-01-24 06:20:00
发表于 2009-07-22 21:15 |显示全部楼层
感谢狼烟给的链接,粗略看了下,发现还是比较难理解

待我仔细看看,慢慢体会之后再来请教

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
发表于 2009-07-23 08:11 |显示全部楼层
就是一回事

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-01-24 06:20:00
发表于 2009-07-23 12:02 |显示全部楼层
翻了好多帖子看,头大之余,觉得还是lululau帖子里面画的图比较容易理解,感谢lululau

对于我主题贴中的脚本中涉及到的变量$a和$$,我是这么理解的:第一次运行a脚本,用了()来fork subshell,但是在这之前,$a和$$变量已经被扩展,事实上在该subshell中两个echo命令参数根本就不是subshell中的$a和$$变量,而是确定的两个数字;前者在subshell中还没有定义,后者在subshell其实也不是parent shell的进程ID值。后来修改之后的a脚本,因为没有先一步的变量扩展,因此echo的$a和$$显示了subshell中“正确”的值。这个应该是造成未export的变量在() fork的subshell中能够被继承假象的原因!?

[ 本帖最后由 Minsic 于 2009-7-23 12:03 编辑 ]

论坛徽章:
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
发表于 2009-07-23 12:21 |显示全部楼层
还没有执行到怎么会被展开。

参见waker的贴子。

另外() 即nested subshell和script subshell不尽相同。

更正:fork exec是两个独立的系统调用,通常先fork再exec,配合使用。但也可以单独调用。

[ 本帖最后由 blackold 于 2009-7-23 18:12 编辑 ]

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-01-24 06:20:00
发表于 2009-07-23 12:59 |显示全部楼层

回复 #6 blackold 的帖子

变量展开难道不是在命令被执行前就完成的么?

总是fork-exec?你的意思是狼烟给的链接里,lululau的图描述的还是有问题的?

nested subshell和script subshell不尽相同?不尽相同在哪里?

猫头鹰大哥能否更多解释几句?谢谢

论坛徽章:
8
摩羯座
日期:2014-11-26 18:59:452015亚冠之浦和红钻
日期:2015-06-23 19:10:532015亚冠之西悉尼流浪者
日期:2015-08-21 08:40:5815-16赛季CBA联赛之山东
日期:2016-01-31 18:25:0515-16赛季CBA联赛之四川
日期:2016-02-16 16:08:30程序设计版块每日发帖之星
日期:2016-06-29 06:20:002017金鸡报晓
日期:2017-01-10 15:19:5615-16赛季CBA联赛之佛山
日期:2017-02-27 20:41:19
发表于 2009-07-23 13:14 |显示全部楼层

回复 #7 Minsic 的帖子

$a被展开了么?
a=3
(a=2;echo $a)


fork和exec是两个步骤
父进程里有个变量a;fork以后子进程里也有一个和父进程里一样的变量a;它在两个进程中的虚拟储存位置和储存内容都是一样的,否则怎么叫fork呢?在一些实现里fork的实现叫clone,这个就更贴切了吧?

论坛徽章:
0
发表于 2009-07-23 13:23 |显示全部楼层
bash 的实现就是如此,应该不是预先展开的原因,man bash得到的话:
       $      Expands  to  the  process  ID of the shell.  In a () subshell, it expands to the process ID of the current shell, not the  subshell.

论坛徽章:
1
数据库技术版块每日发帖之星
日期:2016-01-24 06:20:00
发表于 2009-07-23 13:29 |显示全部楼层

回复 #8 waker 的帖子

唉~看了这个例子就明白了,想得走火入魔牛角尖了 -_-

fork这样解释我是明白了……但是总是fork-exec是啥意思?另外一直只知道exec就是用一个新的进程来替换原有的进程,在这个过程中,是怎么处理那些变量的?包括一般的变量和环境变量,还比如一些类似$$这样的变量(这些不应该是环境变量吧……)?

对于我主题贴提到的例子,两次subshell中的$a和$$变量不同该怎么解释?就是黑哥提到的nested subshell和script subshell的区别吗?

好像越来越混乱了……

[ 本帖最后由 Minsic 于 2009-7-23 13:31 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP