exec执行普通文件和解释器文件的区别
1. 从一个问题开始
首先要从项目中遇到的一个问题说起。编写一个python文件test.py,文件test.py内容如下:
#! /usr/bin/python
....
如果在命令行方式执行test.py的方式是:
test.py -in inputfile -out outputfile;或python test.py -in inputfile -out outputfile;
但是因为需要,用exec函数(这里使用execl)去调用这个python文件。在项目中是这样写的:
execl(”test.py”,”-in”,”inputfile”,”-out”,”outputfile”,(char*)0);
但执行结果并不是预想的test.py执行,而是启动了python交互程序,不知道是什么原因。因为一直以为如果写一个C程序,比如main。那么在命令行输入:main arg1 arg2执行的效果和execl(”main”,”arg1”,”arg2”,(char*)0)的效果应该是一样的。
当然同时伴随我有另一个问题:
execl(“usr/bin/python”,”test.py”,(char*)0);和输入命令”/usr/bin/python test.py”有什么区别?
为了回答些问题,自己通过再反复看apue和做实验测试,终于一点一点明白了,下面就来一点一点的分析。
2. 命令行执行程序和exec执行程序的区别
首先我们来分析一下在命令行执行一个程序和通过exec函数执行程序有什么区别,或者说需要注意的地方(一下所有编写的文件都在/mnt/hgfs/VWShared/目录下)。
编写程序foo.c如下,并编译为可执行文件foo。它打印参数列表(argv)的所有参数.
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);
}
再编写main.c如下,将其编译为可执行文件main,它使用execl调用foo。
l main.c
#include
#include
int main(int argc,char* argv[])
{
int n=0;
if( (n=execl(/mnt/hgfs/VWShared/foo,(char*)0))==-1 )
{
perror(execl error);
exit(0);
}
exit(1);
}
直接在命令行下运行foo,结果如图1:
![](../img/eep/emb/emb-501374bjbea0view.jpg)
图1
运行main(通过execl运行foo)结果如图2:
![](../img/eep/emb/emb-50138cwnovudxyj3.jpg)
图2
可以看出直接在命令行运行foo,则”./foo”被当做argv[0],但是通过exec运行foo发现并没有参数传入foo(程序没有任何输出),也就是说argc值为0。这是什么原因呢?我们知道argv存放的是传递给main函数的命令行参数,当在命令行键入”./foo”时,唯一的命令行参数”./foo”就被传入给main的argv了。所以直接在命令行运行foo就打印出唯一的参数”./foo”。
那么execl的情况呢?首先看一下execl的原型:
int execl(const char* pathname,const char* arg0,.../*(char*)0*/);
注意到了吧,第一个参数是要执行的程序名,第二个参数才是要传入待执行程序的第一个参数,而上述main.c中没有第二个参数(这里说的是execl的第二个参数),也就是没有给foo传递任何参数,foo的参数表argv当然就是空了,或者说argc为0。
通过这个例子我们要有以下认识:
argv[0]不一定就是所执行程序的名称,确切的说它只是命令行的第一个参数,只是通常启动程序是在命令行键入程序名称启动的,所以程序的名称才成为argv[0]。但是也有情况argv[0]不是程序名称的,如:
(1) 通过exec执行时,argv[0]是什么要视exec的参数来定。
例如:我们将main中的execl语句改为:execl(/mnt/hgfs/VWShared/foo,xxxxx,(char*)0);
再运行main,效果如图3:
![](../img/eep/emb/emb-50139mmjlw0plyjr.jpg)
图3
可以看到argv[0]变为了我们传入的参数”xxxxx”。
(2) 通过程序别名启动时,argv[0]就是程序的别名。如我们给foo创建一个软连接sfoo,然后执行sfoo效果如图4:
![](../img/eep/emb/emb-50140r5adeadfkey.jpg)
图4
可以看出输出的argv[0]是./sfoo 而不是./foo,再次证明argv[0]是什么和程序名称无关,只是和传入的命令行第一个参数有关。
补充:在创建上述软连接过程中遇到了一点小问题,不妨也在这里写下来:
在编译VMware下的Linux系统对从Windows中共享过来的文件,进行编译的时候,遇到:ln: creating symbolic link XXXXXX : Operation not supported
出现这类问题,主要是由于在编译的时候,要用ln去建立一些软链接,而这些文件是从Windows中,通过VMWare虚拟机共享进Linux的,而虽然此种操作在Linux系统中很常见,但Windows不支持,所以,编译会报错。比较方便的解决办法是先将文件考到linux的其他目录,再在其他非共享目录中创建软连接。另外还有个解决办法就是,在VMWare下的Linux中,建立Samba服务,然后新创建新samba用户和文件夹,然后在windows中就可以访问到该文件夹了。然后把在Linux中,从共享目录拷贝到你所要共享的samba目
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)