exec执行普通文件和解释器文件的区别
录中,这样,也可以实现我们所要的文件共享。此时在去编译这些代码的时候,由于是在Linux系统中的,所以就OK了。
3. 解释器文件和解释器
先解释两个概念;解释器文件和解释器。
l 解释器文件:一种文本文件,开头通常是:#! pathname [option-argument];比较常见的是#! /bin/bash,shell脚本和python脚本都属于解释器文件。
l 解释器:解释器文件第一行中pathname指定的程序,如bash。
3.1 解释器文件的执行
当执行(exec)解释器文件时,exec系统调用会识别这种文件,内核使调用exec函数的进程实际执行的并不是该解释器文件,而是pathname指定的解释器。
我们可以自己写一个解释器,如之前所写的foo.c:
l foo.c
#include
int
main(int argc,char* argv[])
{
int i;
for(i=0;i
printf(argv[%d]: %s\n,i,argv[i]);
exit(0);
}
编译成为foo然后保存在/mnt/hgfs/VWShared/。
下面我们在自己写一个”解释器文件”——test:
l test
#!/mnt/hgfs/VWShared/foo
3.1.1 通过命令行执行解释器文件
直接在命令行中键入:”./test”,运行test,效果如图5。
![](../img/eep/emb/emb-50141di0qcflnngk.jpg)
图5
将test内容修改为:#!/mnt/hgfs/VWShared/foo argA argB,再次在命令行运行test,效果如图6。
![](../img/eep/emb/emb-50142pdv0aoo32wn.jpg)
图6
通过这两个例子,可以看出命令行运行时当执行文件是”解释器文件”时,参数是如何传递给解释器的:
(1) 通过执行”解释器文件”执行解释器,传递给解释器的第一个参数是解释器文件的pathname,即解释器的路径。
(2) “解释器文件”中pathname后的可选参数(这里的argA,argB)如果存在的话会一起作为第二个参数传递给解释器。
(3) “解释器文件”名称会作为下一个参数传递给解释器。
3.1.2 通过execl执行解释器文件
接下来通过execl执行解释器文件test,修改main中的exec语句如下:
execl(/mnt/hgfs/VWShared/test,arg1,”arg2”,(char*)0));然后执行main,效果如图7。
![](../img/eep/emb/emb-501431bictrnsw5k.jpg)
图7
从这个例子可以了解当执行文件是解释器文件时,内核如何处理exec函数的参数及解释器文件第一行的可选参数。我们知道执行解释器文件实际是执行解释器,由解释器去读取解释器文件中的语句执行,而第一行的pathname以#开头在执行时会被当做注释忽略。下面就让我们分析一下最终传入解释器foo的参数都是什么。
(1) argv[0]是该解释器文件的pathname;
(2) argv[1]是该解释文件中的可选参数;
(3) argv[2]是解释器文件本身名字;
(4) argv[3]是execl出入的第二个参数(第一个参数是arg1)。
那么问题出现了,我们传入execl的arg1去哪里了呢?其实这就是exec执行”解释器文件”和执行一般程序的不同之处:在执行一般程序时,execl(const char* pathname,const char* arg0,...,(char*)0)中的arg0会被当做执行程序(pathname)的第一个参数argv[0],而在执行解释器文件时,内核取execl调用中的pathname而非第一个参数(arg0)作为第一个参数传递给解释器,因为一般而言,第一个参数arg0通常是解释器文件的名字,而pathname包含了比arg0更多的信息(解释器文件的完整路径)。所以当execl执行解释器文件时第一个参数arg0是无效的。
为了说明这个问题,我们再举一个例子,编写python文件pyth.py如下:
l pyth.py:
#! /usr/bin/python
import sys
for i in range(0,len(sys.argv)):
print argv[%d]: %s%(i,sys.argv[i])
它的功能和foo一样同样是打印每个命令行参数。我们分别将main中的execl语句改为:
execl(/mnt/hgfs/VWShared/foo,arg1,arg2,(char*)0))和
execl(/mnt/hgfs/VWShared/pyth.py,arg1,arg2,(char*)0)),对比execl一般程序(foo)和解释器文件(pyth.py)的效果如图8、9。
![](../img/eep/emb/emb-50144ip4bldafiyz.jpg)
图8.execl(/mnt/hgfs/VWShared/foo,arg1,arg2,(char*)0))结果
![](../img/eep/emb/emb-50145kwkp4hjfgym.jpg)
图9.execl(/mnt/hgfs/VWShared/pyth.py,arg1,arg2,(char*)0))结果
可以看出execl对于执行普通文件和解释器文件选取第一个参数是不同的。
3.2 execl执行解释器文件和命令行执行解释器文件的不同
我们上面已经看到execl(/mnt/hgfs/VWShared/pyth.py,arg1,arg2,(char*)0))的结果(图9),下面我们试一下命令行方式:pyth.py arg1 arg2,结果图10:
![](../img/eep/emb/emb-501464p0bwalsyn4.jpg)
图10
可以看到结果和通过execl执行是有区别的,通过命令行执行解释器文件就像通过命令行执行普通程序一样,程序名称作为第一个参数,命令行后面依次作为后续参数。正因为对于解释器文件的execl方式和命令行方式执行时选取第一个参数的方式不同,所以对于解释器文件a.py:
(1) 在命令行输入:./a.py a
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)