execl,execlp,execle
第一个参数是exec系列函数告诉将要运行什么程序(区别就是execlp可以就是命令的名字,而execl和execle需要完整路径名)
第一个命令行的参数必须是程序名,因此第二个参数和第一个参数是一致的
中间都被当做脚本所需要的参数
最后一个参数是NULL,告诉函数没有其他参数了
如果是以e结尾的exec系列函数(例如execle),还可以传递环境变量数组
例子:
execl('/tmp/test', '/tmp/test', 'param1', 'param2', 'param3', NULL);
execlp('test', 'test', 'param1', 'param2', 'param3', NULL);
execle('/tmp/test', '/tmp/test', 'param1', 'param2', 'param3', NULL, env_vars);
execv,execvp,execve
参数类型,只是把后面的参数传递给了数组
例子:
execv('/tmp/test', my_args);
execvp('test', my_args);
错误信息的一些规定
不允许操作 1
没有该文件或目录 2
没有改进程 3
错误 -1
正常返回 0
例子
#include <stdio.h>
/*
为了使用exec函数
*/
#include <unistd.h>
/*
为了使用errno变量
*/
#include <errno.h>
#include <string.h>
int main()
{
if (execl("/sbin/ifconfig", "/sbin/ifconfig", NULL) == -1)
{
if (execlp("ipconfig", "ipconfig", NULL) == -1)
{
fprintf(stderr, "Cannot run ipconfig: %s", strerror(errno));
return 1;
}
}
return 0;
}
fork
fork会向子进程返回0,父进程返回非0值
copy-on-write
为了让fork进程变快,操作系统做了很多技巧,比如操作系统不会真的复制父进程的数据,而是让父子进程共享数据,当子进程需要修改存储器,就会为他复制一份数据
重点
exec系列函数执行的时候会启动一个进程,后面的代码不会运行
伪代码:
code1
exec系列函数
code2
此例中的code2代码不会再运行
如果需要运行获取多个exec系列函数的结果需要使用fork进行
伪代码:
code1
pid_t pid_t = fork();
exec系列函数
pid_t pid_t = fork();
exec系列函数
事例(此事例中需要安装python环境,下载rss gossip脚本https://github.com/dogriffiths/rssgossip/zipball/master)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
int main(int argc, char *argv[])
{
char *feeds[] = {"http://wwww.cnn.com/rss/celebs.xml",
"http://www.rollingstone/rock.xml",
"http://eonline.com/gossip.xml"
};
int times = 3;
char *phrase = argv[1];
int i;
for(i = 0; i< times; i++) {
char var[255];
sprintf(var, "RSS_FEED=%s", feeds[i]);
char *vars[] = {var, NULL};
/*
pid_t是可以理解成一种int的类型
*/
pid_t pid_t = fork();
if (pid_t == -1) {
fprintf(stderr, "can't fork process:%s\n", strerror(errno));
return 1;
}
if (!pid_t && execle("/usr/bin/python", "/usr/bin/python", "./rssgossip.py", phrase, NULL, vars) == -1) {
fprintf(stderr, "can't run script:%s\n", strerror(errno));
return 1;
}
}
return 0;
}