LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
12
返回列表 发新帖
楼主: kiron

Linux解释器原理

[复制链接]
 楼主| 发表于 2005-5-23 12:11:54 | 显示全部楼层
Post by jovesky
整个过程是这样的吧:
对于

  1. int
  2. main(void)
  3. {
  4.   execl("/home/kiron/testexec", "testexec", "arg1", "arg2", (char *) 0);
  5.   return 0;
  6. }
复制代码

就是形成执行序列:/home/kiron/testexec testexec arg1 arg2。然后/home/kiron/testexec在被替换为/home/kiron/showargs addargs,也就是形成了:
/home/kiron/showargs addargs testexec arg1 arg2。
那么为什么最后testexec变成了/home/kiron/testexec啊。还有,如果我把
execl("/home/kiron/testexec", "testexec", "arg1", "arg2", (char *) 0);改成
execl("/home/kiron/testexec",  (char *) 0);的话,/home/kiron/testexec还是会输出的。这时后的执行序列不是变成/home/kiron/showargs addargs了吗,为什么还有/home/kiron/testexec呢?

其实也就是你最初“卖关子”没说的地方最后我还是没看明白。
麻烦斑竹大人帮忙再解释一下下。。


在第二段,我写了以下的文字:

对于解释器,exec族函数是这样做的(以execl为例),如果path是指向了一个脚本,脚本的第一行以#!开头,则这样调用:
以#!后面的字符串为命令,后面加上execl参数列表中指定的参数列表,这样形成了新的程序执行。

那就是说对于机器可执行的程序,exec就是直接形成执行的序列.
对于脚本,exec这是样做的(如testexec脚本)
将脚本的#!后面的字符串/home/kiron/showargs addargs再加上execl中参数的列表:/home/kiron/testexec arg1 arg2

这样就形成了/home/kiron/showargs addargs /home/kiron/testexec arg1 arg2
所有的命令和程序都是以上面的形式形成的(除了系统初始进程init和在init之前的一些原始进程)
回复 支持 反对

使用道具 举报

发表于 2005-5-23 13:10:36 | 显示全部楼层
Post by kiron
在第二段,我写了以下的文字:

对于解释器,exec族函数是这样做的(以execl为例),如果path是指向了一个脚本,脚本的第一行以#!开头,则这样调用:
以#!后面的字符串为命令,后面加上execl参数列表中指定的参数列表,这样形成了新的程序执行。

那就是说对于机器可执行的程序,exec就是直接形成执行的序列.
对于脚本,exec这是样做的(如testexec脚本)
将脚本的#!后面的字符串/home/kiron/showargs addargs再加上execl中参数的列表:/home/kiron/testexec arg1 arg2

这样就形成了/home/kiron/showargs addargs /home/kiron/testexec arg1 arg2
所有的命令和程序都是以上面的形式形成的(除了系统初始进程init和在init之前的一些原始进程)


你说的我明白了,但是还有一点我没明白,为什么我/home/kiron/testexec arg1 arg2这三个参数的哦不加,也能输出arg[2]: /home/kiron/testexec这一行啊?
还有,第二个参数不是testexec吗,为什么后来输出时又加上了全路径呢?
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-24 13:08:02 | 显示全部楼层
Post by jovesky
整个过程是这样的吧:
对于

  1. int
  2. main(void)
  3. {
  4.   execl("/home/kiron/testexec", "testexec", "arg1", "arg2", (char *) 0);
  5.   return 0;
  6. }
复制代码

就是形成执行序列:/home/kiron/testexec testexec arg1 arg2。然后/home/kiron/testexec在被替换为/home/kiron/showargs addargs,也就是形成了:
/home/kiron/showargs addargs testexec arg1 arg2。
那么为什么最后testexec变成了/home/kiron/testexec啊。还有,如果我把
execl("/home/kiron/testexec", "testexec", "arg1", "arg2", (char *) 0);改成
execl("/home/kiron/testexec",  (char *) 0);的话,/home/kiron/testexec还是会输出的。这时后的执行序列不是变成/home/kiron/showargs addargs了吗,为什么还有/home/kiron/testexec呢?

其实也就是你最初“卖关子”没说的地方最后我还是没看明白。
麻烦斑竹大人帮忙再解释一下下。。


哦。。。
我明白你哪里出错了
平常我们传递main(int argc, char **argv)中参数大家都觉得会很平常
现在我们用exec族函数传递给可执行程序的main的参数也是exec中的一些参数,
我这里说的加上execl参数列表中指定的参数列表是指execl传递给可执行程序的参数列表。
像execl("/home/kiron/testexec", "testexec", "arg1", "arg2", (char *) 0);
相当于/home/kiron/testexec arg1 arg2
注意:少了execl中的第二个参数testexec
另外请man execl
回复 支持 反对

使用道具 举报

发表于 2005-5-25 11:18:02 | 显示全部楼层
还是不完全明白,不过有一点知道了,是不是#!在调用解释器执行时,需要调用exec函数啊?
如果是的话,怎么设置exec的参数呢?问题还是这样:开始的时候只有一个回射函数和一个脚本。为什么回射时会吧脚本名称也回射出来,是在调用exec时把脚本名称作为参数了吗?
所以再请斑竹详细解释一下#!在调用解释器时对exec的调用和exec参数的设置!
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-5-25 13:52:23 | 显示全部楼层
Post by jovesky
还是不完全明白,不过有一点知道了,是不是#!在调用解释器执行时,需要调用exec函数啊?
如果是的话,怎么设置exec的参数呢?问题还是这样:开始的时候只有一个回射函数和一个脚本。为什么回射时会吧脚本名称也回射出来,是在调用exec时把脚本名称作为参数了吗?
所以再请斑竹详细解释一下#!在调用解释器时对exec的调用和exec参数的设置!



现在问题越来越偏离了我的初衷,我只是想让大家了解一下系统里是怎么对待解释器脚本的

现在讨论到了LINUX的系统编程了。
在APUE里有大概这样的描述(家里才有书,现在手头上没有只能讲出意思):
exec对传给它的设置了执行位的文件,它会检查它,
如果是机器可执行的,则把arg0,arg1....传给此机器可执行程序,开始执行此程序。
如果不是机器可执行的,则将认为它是一个脚本文件,然后检查此文件的第一行中的开头的#!,如果第一行没有#!,可能就退出程序了(这个应该是依赖于实现?)。如果有开头的#!,便按照上面我的帖子里的描述,把#!后面的字串加上exec参数里应该传给可执行文件的参数列表,这个参数列表相当于我们在shell里输入的:
$ ls -l
这样的序列。
对于execl函数,不知道你有没有man过?
int execl(const char *path, const char *arg, ...);
第一个参数是你要执行的文件的路径,第二个参数是基本的不带路径的文件名,后面就是argv[1],argv[2]了。
那么实际要传给脚本文件的参数为:/home/kiron/testexec arg1 arg2
这并不是可有可无的全路径,但你可以把它改成相对路径(这样上面的就该改成: ./PHTH/testexec arg1 arg2了),这是可行的,但绝不能使用~这样的符号,这是由shell扩展的,和exec是无关的。对于第二个参数arg,则是用来确定一下文件的程序名
execl这样才能指定怎么找到testexec。
前面已经说了,是#!后面的字串,加上实际要传给脚本文件的参数:/home/kiron/testexec arg1 arg2形成了:
/home/kiron/showargs addargs /home/kiron/testexec arg1 arg2
如果你在execl用了相对路径:
/home/kiron/showargs addargs ./PATH/testexec arg1 arg2
然后就形成了新的执行序列,这个序列的效果和你在shell提示符下输入相应的序列的效果是一样的

另外纠正你的一些说法:
------------------------------------------------------------------------------------------------------------
所以再请斑竹详细解释一下#!在调用解释器时对exec的调用和exec参数的设置!
------------------------------------------------------------------------------------------------------------
不是#!调用解释器
而是exec脚本文件时,会找出解释器(由#!行来找出)来对此脚本进行解释执行。(你可以想像成找出解释器后以上面的规则来形成新的序列来再exec一次解释器)
exec参数的设置不应该由我来详细说明,尽管我已经在上面解释了。这个应该由你自己去man或写几个程序来帮助理解一下。
回复 支持 反对

使用道具 举报

发表于 2005-6-4 22:44:41 | 显示全部楼层
两位讨厌的编程,不太明白,不过版主讲的linux解释器原理倒是明白
毕竟还要再多看几次这个文章
回复 支持 反对

使用道具 举报

发表于 2005-10-20 19:43:15 | 显示全部楼层
终于看明白了,感谢楼主!
不过,感觉楼主的表达不是很直接,弄的我开始也一头雾水
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表