免费注册 查看新帖 |

Chinaunix

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

[系统管理] 在shell十三问中发现一个的问题,大家来指点指点 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-04-09 22:26 |只看该作者 |倒序浏览
#!/bin/bash
A=B
echo "ID for 1.sh before exec/source/fork$"
export A
echo "1.sh: \$A is $A"
case $1 in
        exec)
                echo "using exec..."
                exec ./sh2.sh ;;
        source)
                echo "using source..."
                source ./sh2.sh ;;
        *)
                echo "using fork by default..."
                 ./sh2.sh ;;
esac
echo "ID for 1.sh after exec/source/fork$"
echo "1.sh: \$A is $A"





#!/bin/bash
#sh2.sh
echo "ID for 2.sh: $$"
echo "$(ps -o pid,ppid)"  #这是我自己添加的一行代码,用于显示父子进程
echo "2.sh get \$A=$A from 1.sh"
A=C
export A
echo "2.sh: \$A is $A"

这是十三问中的一个例子,小弟在这里发现一个问题
如果在bash键入:
./sh1.sh
打印出的父子进程关系下所示
  PID  PPID
2508  2498
2898  2508
2899  2898
2900  2899
2508是一个bash进程的进程ID,2898(其父进程是2508)是执行sh1.sh脚本的bash进程,根据流程应该走到           ./sh2.sh ;;   这一步,此时又会生成一个bash(其父进程为2898)进程为2899,在遇到sh2.sh脚本的ps命令后,bash又分化出一个子进程2900(其父进程为2899)执行ps指令;这里netman大大说子进程设置的环境变量不会被父进程得到,这点是对的。

如果在bash键入:
./sh1.sh exec
打印出的父子进程关系下所示
  PID  PPID
2508  2498
2908  2508
2909  2908
2508同样是bash的进程ID,2508生成一个子bash(进程ID为2808,父进程ID为2508)执行sh1.sh脚本,根据流程应该走到     exec ./sh2.sh ;;此时还是由2808的bash执行sh2.sh脚本,然后在遇到ps命令后,2808产程2909执行ps命令。这里netman大大说子进程设置的环境变量不会被父进程得到,这点是对的。

如果在bash键入:
./sh1.sh source
打印出的父子进程关系下所示
  PID  PPID
2508  2498
2924  2508
2925  2924
2926  2925
结果分析同第一个,这里最后却显示子进程设置的环境变量既然被父进程的到了!

这是问题一

未完待续……………………


论坛徽章:
0
2 [报告]
发表于 2014-04-09 22:57 |只看该作者
这里第三点可能分析错误
假设sh3.sh如下
#!/bin/bash
echo "PID for sh3.sh: $$"
echo "$(ps -o pid,ppid)"
A=C
export A

直接在终端执行
source  ./sh3.sh
输出为:
PID for sh3.sh: 2146
  PID  PPID
2146  213
2217  2146
2218  2217

这里我们可以看到执行sh03.sh的bash进程确实没变,是2146,执行ps命令需要一个子进程,总共只需两个进程,那么何这里有三个进程呢?

论坛徽章:
0
3 [报告]
发表于 2014-04-09 23:00 |只看该作者
所以说,netman大哥说的子进程环境变量确实不会被父进程得到(这一点在AUPE中也说明过),问题最后归结到执行 source ./sh3.sh为何出现了两个子进程

论坛徽章:
0
4 [报告]
发表于 2014-04-10 09:24 |只看该作者
怎么木人提点意见啊啊啊啊啊啊

论坛徽章:
0
5 [报告]
发表于 2014-04-10 09:35 |只看该作者
source reads commands from name. source commands can be nested, but if they are nested too
       deeply  the shell can run out of file descriptors. An error in a sourced file at any level
       terminates all nested source commands.

我想source虽然说法是在当前shell中执行source 后面的command. 没有fork shell.
但source这个命令可能需要一个单独的process来存在.

论坛徽章:
11
金牛座
日期:2015-03-19 16:56:22数据库技术版块每日发帖之星
日期:2016-08-02 06:20:00数据库技术版块每日发帖之星
日期:2016-04-24 06:20:00数据库技术版块每日发帖之星
日期:2016-04-13 06:20:00IT运维版块每日发帖之星
日期:2016-04-13 06:20:00数据库技术版块每日发帖之星
日期:2016-02-03 06:20:00数据库技术版块每日发帖之星
日期:2015-08-06 06:20:00季节之章:春
日期:2015-03-27 15:54:57羊年新春福章
日期:2015-03-27 15:54:37戌狗
日期:2015-03-19 16:56:41数据库技术版块每日发帖之星
日期:2016-08-18 06:20:00
6 [报告]
发表于 2014-04-10 09:44 |只看该作者
本身属于bash 的子进程 。。。。

论坛徽章:
0
7 [报告]
发表于 2014-04-10 10:10 |只看该作者
回复 5# runintostar
我是这样理解的,source命令属于shell内嵌的命令(type source),即使source确实要一个子进程来执行,那也是bash经过fork然后exec(source),也就是说最后这个肯定为原本bash的子进程,子进程设置的环境变量如何被父进程bash得到啊?(source命令执行的脚本,脚本中export变量可以在父bash进程中存在)


   

论坛徽章:
0
8 [报告]
发表于 2014-04-10 10:12 |只看该作者
回复 6# liaosnet


这位大哥是跟上面那位大哥一个意思吗?就是说source也需要一个子进程来执行?那子进程设置的环境变量如何被父进程得到呢?   

论坛徽章:
93
2015年辞旧岁徽章
日期:2019-10-10 10:51:15CU大牛徽章
日期:2014-02-21 14:21:56CU十二周年纪念徽章
日期:2020-10-15 16:55:55CU大牛徽章
日期:2014-02-21 14:22:07羊年新春福章
日期:2019-10-10 10:51:39CU大牛徽章
日期:2019-10-10 10:55:38季节之章:春
日期:2020-10-15 16:57:40ChinaUnix元老
日期:2019-10-10 10:54:42季节之章:冬
日期:2019-10-10 10:57:17CU大牛徽章
日期:2014-02-21 14:22:52CU大牛徽章
日期:2014-03-13 10:40:30CU大牛徽章
日期:2014-02-21 14:23:15
9 [报告]
发表于 2014-04-10 10:32 |只看该作者
source 是内建命令,按理应该不用另外起子进程吧。

论坛徽章:
0
10 [报告]
发表于 2014-04-10 10:37 |只看该作者
回复 7# 王华_

shell builtin?
export 是 shell builtin么. 如果export这个命令是bash fork出来的一个子进程, 那它后面的语句为什么能让父进程shell中得环境变量改变呢?
source是个builtin, 当然可以确认它是被fork出子进程来执行的了
但是这个子进程具体在做什么? 我们不能认为source sh2.sh, 就是让sh2.sh在被fork出来执行source的这个子进程中进行的.
它的作用只是用来解析后面filename中的command来给父进程执行的
正如你所说, source归根到底, 只是个shell builtin, 它只能做自己的功能, 而不是一个shell.

source is a Unix command that evaluates the file following the command, as a list of commands, executed in the current context.
Frequently the "current context" is a terminal window into which the user is typing commands during an interactive session.

exec 和 fork才是同一个级别的概念. 其他都不是
当然shell里的exec也是个builtin, 但它的功能却是真的exec~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP