exec家族函数
NAME
execl, execlp, execle, execv, execvp, execvpe - execute a file
SYNOPSIS
#include <unistd.h>
extern char **environ;
int execl(const char *pathname, const char *arg, ...
/* (char *) NULL */);
int execlp(const char *file, const char *arg, ...
/* (char *) NULL */);
int execle(const char *pathname, const char *arg, ...
/*, (char *) NULL, char *const envp[] */);
int execv(const char *pathname, char *const argv[]);
int execvp(const char *file, char *const argv[]);
int execvpe(const char *file, char *const argv[],
char *const envp[]);
可以观察一些这一组函数的后缀名称,无非就是在exec函数后面加上 l,p,e,v这几个字母。
l : list => 函数参数列表指定进程参数。
p:path => 到PATH环境变量这个路径中查找可执行程序
e:environ => 父进程提供环境变量
v:数组的方式提供进程参数
进程参数 | 自动搜索PATH | 使用当前环境变量 | |
execl() | 列表 | NO | YES |
execlp() | 列表 | YES | YES |
execle() | 列表 | NO | NO,提供环境变量 |
execv() | 数组 | NO | YES |
execvp() | 数组 | YES | YES |
execve() | 数组 | NO | NO,提供环境变量 |
看一下demo:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc,char* argv[])
{
char pids[32] = {0};
char* const ps_argv[] = {"pstree","-A","-p","-s",pids,NULL};
char* const ps_envp[] = {"PATH=/bin:/usr/bin","TEST=Delphi",NULL};
sprintf(pids,"%d",getpid());
execl("/bin/pstree","pstree","-A","-p","-s",pids,NULL);
execl("pstree","pstree","-A","-p","-s",pids,NULL);
execle("/bin/pstree","pstree","-A","-p","-s",pids,NULL,ps_envp);
execv("/bin/pstree",ps_argv);
execvp("pstree",ps_argv);
execve("/bin/pstree",ps_argv,ps_envp);
return 0;
}
system函数
NAME
system - execute a shell command
SYNOPSIS
#include <stdlib.h>
int system(const char *command);
参数:程序名以及进程参数(如:pstree -A -p -s $$)
返回值:进程退出状态值
下面是system(...) 函数运行原理图,和我们自己创建的create_process(...)原理差不多。
![](https://img-blog.csdnimg.cn/img_convert/783b9338aad0dde9dcd445987cc61c94.png)
来看一下demo1:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
/*
$$ : 表示当前进程的pid
*/
int main(int argc,char* argv[])
{
int result = 0;
printf("current: %d\n",getpid());
result = system("pstree -A -p -s $$");
printf("result = %d\n",result);
return 0;
}
编译输出:
wj@wj:~/WORK/Learning/DT/07/07-3$ gcc test.c -o test.out
wj@wj:~/WORK/Learning/DT/07/07-3$ ./test.out
current: 72319
systemd(1)---systemd(1454)---gnome-terminal-(2307)---bash(57230)---test.out(72319)---sh(72320)---pstree(72321)
result = 0
看一下demo2:
//test.sh
echo "Hello world from shell..."
a=1
b=1
c=$(($a+$b))
echo "c = $c"
wj@wj:~/WORK/Learning/DT/07/07-3$ chmod 777 test.sh
wj@wj:~/WORK/Learning/DT/07/07-3$ ./test.sh
Hello world from shell...
c = 2
看一下demo3:
//test.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
/*
wait: true :代表父进程是否等待子进程结束
wait: false :代表父进程不等待子进程结束
*/
int create_process(char* path,char* const args[],char* const env[],int wait)
{
int ret = fork();
if(ret == 0)
{
if(execve(path,args,env) == -1)
{
exit(-1);
}
}
if(wait && ret) // 1.wait为true。2.并且父进程是否成功创建子进程?来共同解决父进程是否等待子进程结束?
{
waitpid(ret,&ret,0);
}
return ret; //1.如果等待,ret为子进程的退出状态;2.如果不等待,返回为子进程的pid
}
int main(int argc,char* argv[])
{
char* target = argv[1];
char* const ps_argv[] = {target,NULL};
char* const ps_envp[] = {"PATH=/bin:/usr/bin","TEST=Delphi",NULL};
int result =0;
if(argc < 2) exit(-1);
printf("current: %d\n",getpid());
//result = create_process(target,ps_argv,ps_envp,1);
result = system(target);
printf("result = %d\n",result);
return 0;
}
//helloworld.c
#include <stdio.h>
int main(int argc,char* argv[])
{
printf("hello world\n");
return 0;
}
编译运行输出:
wj@wj:~/WORK/Learning/DT/07$ gcc test.c -o test.out
wj@wj:~/WORK/Learning/DT/07$ ./test.out ./helloworld.out
current: 73126
hello world
result = 0
wj@wj:~/WORK/Learning/DT/07$ cp 07-3/test.sh ./
wj@wj:~/WORK/Learning/DT/07$ ls
07-3 helloworld.c helloworld.out test.c test.out test.sh
wj@wj:~/WORK/Learning/DT/07$ ./test.out ./test.sh
current: 73178
Hello world from shell...
c = 2
result = 0
system 和 create_process区别和联系
system创建的是shell进程,功能比较强大,可以直接调用shell进程函数,但是这个功能强大(相对于我们自己创建的create_process函数来说)是以牺牲性能为代价的。
如果用 //result = create_process(target,ps_argv,ps_envp,1); 我们自己创建的create_process,则不能够调用shell进程函数。我们自己创建的create_process效率更高。