exec族函数、system()函数和popen函数

exec族函数:
exec族函数的作用:
(1)一个父进程希望复制自己,使父子进程同时执行不同的代码段,如父进程等待客户端的服务请求。当这种请求到达时,父进程嗲用fork(),使子进程处理次请求,父进程则继续等待下一个服务请求到达。
(2)一个进程要执行一个不同的程序。在这种情况下,子进程fork返回后立即调用exec。

       int execl(const char *path, const char *arg, ...);
       int execlp(const char *file, const char *arg, ...);
       int execle(const char *path, const char *arg,..., char * const envp[]);
       int execv(const char *path, char *const argv[]);
       int execvp(const char *file, char *const argv[]);
       int execvpe(const char *file, char *const argv[],char *const envp[]);

execl:
int execl(const char *path, const char *arg, …);
第一个参数是所需要执行文件或指令的路径,第二个参数是文件名或者指令,第三个参数为调用该文件所需要的参数,每个参数以逗号隔开,最后还需要一个NULL作为execl的结尾。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

//int execl(const char *path, const char *arg, ...);

int main()
{
    int ret = execl("/bin/ls","ls",NULL);//第一个参数为ls的默认路径,使用whereis ls查看文件位置,第二个参数为该文件名,如果使用ls -l指令,就需要在第三个指令处输入"-l"(注意是以指针的形式),并且整个execl函数需要一个NULL进行结尾。

    if(ret == -1){
        printf("execl failed\n");
        perror("why");         //使用失败可以用perror()解析失败原因
    }

    return 0;
}

执行结果:
在这里插入图片描述

execlp
int execlp(const char *file, const char *arg, …);该指令不需要输入执行文件或者命令的路径,第一个参数无需给出具体的路径,只需给出函数名即可,系统会在PATH环境变量中寻找所对应的程序,如果没找到的话返回-1。

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

//int execlp(const char *file, const char *arg, ...);

int main()
{
    int ret = execlp("ls","ls","-l",NULL);

    if(ret == -1){
        printf("execlp failed\n");
        perror("why");
    }else{
       printf("execlp suxxess\n");
    }

    return 0;
}

执行结果:
在这里插入图片描述
execv和execvp只是将execl中的参数定义为一个字符串

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>

//int execl(const char *path, const char *arg, ...);

int main()
{
    char *argv[] = {"ls",NULL}; //将execl中的第二位之后的参数定义为字符串放入execl

    int ret = execv("/bin/ls",argv);

    if(ret == -1){
        printf("execl failed\n");
        perror("why");
    }else{
       printf("execl suxxess\n");
    }

    return 0;
}

执行结果:
在这里插入图片描述
execl与进程的综合应用:
在子进程使用execl执行文件修改配置文件:
配置文件:
test.config

SPEED = 3
CAO = 9
HAI = 1
JAING = 5

修改文件:
change.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>


int main(int argc,char **argv)
{

        char *readBuf = NULL;

        int fd = open(argv[1],O_RDWR|O_CREAT,0600);
        if(fd == -1){
          printf("file open failed\n");
        }

        int cnt = lseek(fd,0,SEEK_END);
        lseek(fd,0,SEEK_SET);

        readBuf= (char*)malloc(cnt*sizeof(char));

        int ret_READ = read(fd,readBuf,cnt);

        char *p = strstr(readBuf,"CAO = ");

        *(p + strlen("CAO = ")) = '2';

        lseek(fd,0,SEEK_SET);
        int ret_WRITE = write(fd,readBuf,cnt);

        close(fd);

        return 0;
}

创建进程文件:
exc.c

include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
        pid_t pid;

        int data;


        while(1){
                printf("please input data\n");

                scanf("%d",&data);

                if(data == 1){
                        pid = fork();

                if(pid > 0){
                        printf("this is father pid\n");
                }else if(pid == 0){
                        execl("./change","change","test.config",NULL);
                }

             }
        }

        return 0;
}

执行后配置文件内容被修改:

SPEED = 3
CAO = 2
HAI = 1
JAING = 5

system函数:
使用system函数结束后,原程序依然能够执行之后的代码,而exec族函数执行完之后程序就飞掉,无法执行函数之后的代码。

int system(const char *command);
如果system()在调用/bin/sh时失败则返回127,其他原因返回-1。若参数为空指针则返回非零值
将exec族函数改用system

include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
        pid_t pid;

        int data;


        while(1){
                printf("please input data\n");

                scanf("%d",&data);

                if(data == 1){
                        pid = fork();

                if(pid > 0){
                        printf("this is father pid\n");
                }else if(pid == 0){
                      system("./change test.config");
                }

             }
        }

        return 0;
}

popen函数:
FILE *popen(const char *command, const char *type);
popen函数需要fread去读取文件执行之后的内容,可以将内容放置于字符串中,只有加上打印字符串的命令,执行结果才能打印在shell里。
popen需要使用pclose对其进行关闭。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//  FILE *popen(const char *command, const char *type);
//int pclose(FILE *stream);
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

int main()
{
     FILE *fp;
     char ret[1024] = {0};

     fp = popen("ls","r");
     int nread = fread(ret,sizeof(char),1024,fp);

     printf("read %d byte from fp,contex is %s",nread,ret);

     return 0;
}

执行结果:
在这里插入图片描述
不加打印内容:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//  FILE *popen(const char *command, const char *type);
//int pclose(FILE *stream);
//size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

int main()
{
     FILE *fp;
     char ret[1024] = {0};

     fp = popen("ls","r");
     int nread = fread(ret,sizeof(char),1024,fp);

   //  printf("read %d byte from fp,contex is %s",nread,ret);

     return 0;
}

执行结果:
在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值