exec族函数
为什么要用exec族函数,有什么用?
- 一个进程希望复制自己,使父,子进程同时执行不同的代码段。这在网络服务进程中是常见的——父进程等待客户端的服务请求。当这种请求到达时,父进程调用fork,使子进程处理此请求。父进程则继续等待下一个服务请求到达。
- 一个进程要执行一个不同的程序。这对shell是常见的情况。在这种情况下,子进程从fork返回立即调用exec。
功能
在调用进程内部执行一个可执行文件。可执行文件既可以是二进制文件,也可以是任何Linux可执行的脚本文件。
函数原型
#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ...);
int execlp(const char *file, const char *arg, ...);
int execv(const char *path, char *const arg[]);
int execvp(const char *file, char *const arg[]);
int execle(const char *path, const char *arg,..., char *const envp[]);
int execvpe(const char *file, char *const argv[], char *const envp[]);
/*
path:可执行文件的路径名字
arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。
*/
返回值
exec函数族的函数执行成功后不会返回,调用失败后,会设置errno并返回-1,然后从原程序的调用点接着往下执行。
// execl的使用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
printf("before execl\n");
if(execl("/bin/ls","ls","-l",NULL) == -1)
{
printf("execl failed!\n");
perror("why"); //显示错误的原因
}
printf("after execl\n");
return 0;
}
//将当前路径添加到环境变量中 export PATH=$PATH:路径
// execlp的使用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
printf("before execl\n");
if(execlp("ps","ps",NULL,NULL) == -1) //不需要whereis找命令的路径
{
printf("execl failed!\n");
perror("why");
}
printf("after execl\n");
return 0;
}
//execvp的使用
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
printf("before execl\n");
char *argv[] = {"ps", NULL, NULL};
if(execvp("ps", argv) == -1)
{
printf("execl failed!\n");
perror("why");
}
printf("after execl\n");
return 0;
}
exec配合fork使用
实现功能:当父进程检测到输入为1的时候,创建子进程把配置文件的字段值修改掉。
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int data;
while(1)
{
printf("please input a data:\n");
scanf("%d", &data);
if(data == 1)
{
int fdSrc;
pid = fork();
if(pid > 0)
{
wait(NULL);
}
if(pid == 0)
{
execl("./changeShu", "changeShu", NULL, NULL);//changeShu为changeData.C编译后的文件
}
}
else
{
printf("wait, do nothing\n");
}
}
return 0 ;
}
//changeData.c文件代码
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
int fdSrc;
char *readBuf = NULL;
fdSrc = open("config.txt", O_RDWR);
int size = lseek(fdSrc, 0, SEEK_END);
lseek(fdSrc, 0, SEEK_SET);
readBuf = (char *)malloc(sizeof(char)*size + 8);
int n_read = read(fdSrc, readBuf, size);
char *p = strstr(readBuf, "LENG=");
if(p == NULL)
{
printf("no found\n");
exit(-1);
}
p = p + strlen("LENG=");
*p = '5';
lseek(fdSrc, 0, SEEK_SET);
int n_write = write(fdSrc, readBuf, size);
close(fdSrc);
return 0;
}
system函数
grep 关键字 *:查找存在关键字的文件
system()函数的返回值:成功,则返回进程的状态值;当sh不能执行时,返回127;失败返回-1.
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
int main()
{
pid_t pid;
int data;
while(1)
{
printf("please input a data:\n");
scanf("%d", &data);
if(data == 1)
{
int fdSrc;
pid = fork();
if(pid > 0)
{
wait(NULL);
}
if(pid == 0)
{
system("./changeShu config.txt");
}
}
else
{
printf("wait, do nothing\n");
}
}
return 0 ;
}
参考:https://www.cnblogs.com/leijiangtao/p/405|387.html
popen函数
比system在应用中的好处:可以获取运行的输出结果
#include <stdio.h>
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);
int main()
{
char ret[1024] = {0};
FILE *fp;
fp = popen("ps", "r");
int nread = fread(ret, 1, 1024, fp);
printf("read ret %d bytes, ret = %s\n", nread, ret);
return 0;
}
参考:https://blog.csdn.net/libinbin_|0|4/article/details/51490568