免费注册 查看新帖 |

Chinaunix

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

怎么理解shell执行命令时是启用了一个新shell?  关闭 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2004-09-10 12:10 |只看该作者 |倒序浏览
DBNAME是在profile里定义的环境变量并被export
所以
echo $DBNAME
sbss

但是
$a=1
而不扩展
那么
echo $a
1
为什么这个a变量被传到子shell了呢

论坛徽章:
0
2 [报告]
发表于 2004-09-10 13:00 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?


  1. 要设计一个测试案例是不容易的。现在还没有想好。
  2. 不过可以给你一点参考

  3. a=b

  4. 首先 type echo 应该是 built-in,当然是在当前的shell运行的。不会启动子shell。所以没有传递的意思。

  5. which echo,应该有/usr/bin/echo

  6. 好的,现在开始
  7. /usr/bin/echo $a

  8. 这一定会启动一个子shell来运行的。但是要注意,当前shell启动shell前,已经做了$a的展开,(set -x看看?)。也就是说,实际传入的命令行为
  9. /usr/bin/echo b
  10. 因此,你看到的还是b,已经被当前shell解析$a后的展开式。但是你由此
  11. 作出a也就子shell继承的推断是有问题的
复制代码

论坛徽章:
0
3 [报告]
发表于 2004-09-10 14:45 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?


  1. 不知道这样的测试,在您的系统是什么结果
  2. set -x            为了能看到您的实际输入

  3. export   var="hello"
  4. avar=" world"
  5. echo "$var" "$avar"
  6. /bin/echo "$var" "$avar"
  7. echo '$var' '$avar'
  8. /bin/echo '$var' '$avar'
  9. eval echo '$var' '$avar'
  10. eval /bin/echo '$var' '$avar'
  11. sh eval echo '$var' '$avar'
  12. sh eval /bin/echo '$var' '$avar'

复制代码

论坛徽章:
0
4 [报告]
发表于 2004-09-10 14:48 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?

原帖由 "ivhb" 发表:

好的,现在开始
/usr/bin/echo $a

这一定会启动一个子shell来运行的。

  1. [x@as bin]# file echo
  2. echo: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), for GNU/Linux 2.2.5, dynamically linked (uses shared libs), stripped
复制代码

是个shell script 时 ,是在subshell中执行的,
echo 是一个二进制的执行文件,怎么会在子shell中执行呢? 这个echo 还是在当前shell中执行阿

论坛徽章:
0
5 [报告]
发表于 2004-09-10 18:26 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?


  1. 就我所知,执行一个二进制文件,一定是exec()来执行的。
  2. 如果是当前进程,exec()执行完该二进制文件后,还能继续运行当前shell么?
复制代码

论坛徽章:
0
6 [报告]
发表于 2004-09-10 19:04 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?

执行完二进制文件是产生个该二进制文件(程序)的新进程,但不是一个shell进程, 所谓在subshell中执行只不过是由subshell产生该程序的进程, 而不是当前shell产生

论坛徽章:
0
7 [报告]
发表于 2004-09-10 19:49 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?

[code]
当前的shell,如果fork了,那么fork之后,有一份当前shell的完整的copy,这个copy,就认为是子shell,然后子shell就execlp指定的文件。
如果当前shell没有fork,就是当前shell中执行。

执行二进制文件里,不fork,exec,那么该二进制文件执行完后,一定是
中止了当前的运行环境。这点应该可以确认的吧。由此我想
我和你的分歧在于,可能是因为父进程fork了,其子进程和本身一样。所以不能成为子shell??

当前shell一旦fork,能说,fork的进程不是shell?只是fork到exec的动作太快,fork出来的子shell的进程空间立马被该二进制文件覆盖。

这是我的理解,还望斧正
[code]

论坛徽章:
0
8 [报告]
发表于 2004-09-10 20:23 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?

谢谢楼上的两位大侠:我明白了。
关键在于:shell 进程与普通的命令进程(也算是shell的子进程,单不是子shell进程,两者的区别就是子shell进程会拥有父shell进程的环境变量的副本,而普通的进程没有,普通的进程就相当于一词函数调用,把我们需要用到的环境变量等传递进去,然后进行操作,很有可能会修改变量的值.)

在命令行执行某个命令时,由primary shell fork 一个普通的进程,并传递需要的变量(可能时常量,比如一个字符串,也可能时一个已经定义了的变量,如环境变量)。但是执行环境并没有改变,普通命令进程通primary的一个共同之处就是:共享标准输入,标准输出等文件。所以尽管在命令进程里进行屏幕打印等操作我们也能看到)。
而在script中执行时,则由primary shell fork 一个sub shell(大概就是primary shell 的copy),所以该sub shell 拥有primary shell 里定义的所有环境变量,只不过是副本了,所以对环境变量的修改不会影响到父shell 进程。

所以 :
$echo $a
实际就是在当前shell环境那执行一个普通命令调用。
$unset a
把a的地址传递给unset命令,在unset命令里清除。这与:
$a=""有类似的功效而已。

综上,所谓shell: 1.充当主进程的角色。
                          2.在其生命期内(没有exit或者log out).维护一些必要的环境变量,供普通命令进程或者sub shell使用。
以上是我的理解,不对的地方请指出。!!
谢谢!!

论坛徽章:
0
9 [报告]
发表于 2004-09-10 20:41 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?

原帖由 "ivhb" 发表:
当前shell一旦fork,能说,fork的进程不是shell?只是fork到exec的动作太快,fork出来的子shell的进程空间立马被该二进制文件覆盖。

当前shell直接就fork 出一个二进制文件的进程, 就不用先fork个subshell再exec了,那是浪费资源
pinecrane说的是正确的

论坛徽章:
1
荣誉版主
日期:2011-11-23 16:44:17
10 [报告]
发表于 2004-09-11 01:09 |只看该作者

怎么理解shell执行命令时是启用了一个新shell?

[quote]原帖由 "compnik"]当前shell直接就fork 出一个二进制文件的进程, 就不用先fork个subshell再exec了,那是浪费资源 [/quote 发表:

這個我也不確定, 但從眾多文件的說明上, 似乎大都說是先 fork 再 exec 再 exit 的...

a=b
/bin/echo $a
理解上, a 是一個 local var, 不會被帶進 child env 中的.
但為何可以看到呢?
嗯... 看過 shell 十三問的朋友, 一定記得我最少強調過兩次如下的觀念了:
---> 在 command line 中的變數替換完成後, 會重組命令行!

因此, /bin/echo $a 在完成替換後, 會被重組為 /bin/echo b ,
然後才 fork & exec ...
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP