Linux下exec系列函数的使用

Linux系统中,我们可以使用可以使用system函数和exec系列的函数调用另一个可执行文件或调用命令。

exec系列函数简单介绍

#include <unistd.h>
extern char **environ;
int execl(const char *path, const char *arg, ... /* (char  *) NULL */);
int execlp(const char *file, const char *arg, ... /* (char  *) NULL */);
int execle(const char *path, const char *arg, ... /*, (char *) NULL, 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[]);

函数返回值:
成功: 函数不会返回
出错: 返回-1,失败原因记录在error中。

函数之间的区别

  1. 路径还是文件名
    execl、execle、execv函数取路径作为参数,execlp、execvp、execvpe取文件名作为参数
  2. 参数表传递
    函数execl、execlp、execle要求将新程序的每个命令行参数都说明为一个单独的参数,这种参数以空指针结束。
    函数execv、execvp、execvpe应该先构造一个指向各个参数的指针数组,然后将该数组的地址作为函数的参数。
  3. 向新程序传递环境表
    execle可以传递一个直线环境字符串指针数组的指针
    其他的函数则使用进程中的environ变量为新程序复制现有的环境。

实验记录

  1. 带l 的exec函数:execl,execlp,execle,表示后边的参数以可变参数的形式给出且都以一个空指针结束。

示例:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    printf("entering main process---\n");
    execl("/bin/ls","ls","-l",NULL);
    printf("exiting main process ----\n");
    return 0;
}

在这里插入图片描述
2. 带 p 的exec函数:execlp,execvp,表示第一个参数path不用输入完整路径,只有给出命令名即可,它会在环境变量PATH当中查找命令
示例:带p但没给出完整路径

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    printf("entering main process---\n");
    execl("ls","ls","-al","~",(char *)0);
    printf("exiting main process ----\n");
    return 0;
}

结果:
在这里插入图片描述
现在带p:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(void)
{
    printf("entering main process---\n");
    execlp("ls","ls","-al","~",(char *)0);
    printf("exiting main process ----\n");
    return 0;
}

在这里插入图片描述

  1. 不带 l 的exec函数:execv,execvp表示命令所需的参数以char *arg[]形式给出且arg最后一个元素必须是NULL
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main(void)
{
    printf("entering main process---\n");
    int ret;
    char *argv[] = {"ls","-l",NULL};
    ret = execvp("ls",argv);
    if(ret == -1)
        perror("execl error");
    printf("exiting main process ----\n");
    return 0;
}

结果
在这里插入图片描述

  1. 带 e 的exec函数:execle表示,将环境变量传递给需要替换的进程

从上述的函数原型中我们发现:

extern char **environ;

此处的environ是一个指针数组,它当中的每一个指针指向的char为“XXX=XXX”

environ保存环境信息的数据可以env命令查看:
在这里插入图片描述
它由shell进程传递给当前进程,再由当前进程传递给替换的新进程。

示例:execle.c

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

int main(int argc, char *argv[])
{
    //char * const envp[] = {"AA=11", "BB=22", NULL};
    printf("Entering main ...\n");
    int ret;
    ret = execl("./hello", "hello", NULL);
    //execle("./hello", "hello", NULL, envp);
    if(ret == -1)
        perror("execl error");
    printf("Exiting main ...\n");
    return 0;
}

hello.c

#include <unistd.h>
#include <stdio.h>
extern char** environ;

int main(void)
{
    printf("hello pid=%d\n", getpid());
    int i;
    for (i=0; environ[i]!=NULL; ++i)
    {
        printf("%s\n", environ[i]);
    }
    return 0;
}

在这里插入图片描述
可知原进程确实将环境变量信息传递给了新进程

那么现在我们可以利用execle函数自己给的需要传递的环境变量信息:

示例程序:execle.c

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

int main(int argc, char *argv[])
{
    char * const envp[] = {"AA=11", "BB=22", NULL};
    printf("Entering main ...\n");
    int ret;
    //ret =execl("./hello", "hello", NULL);
    ret =execle("./hello", "hello", NULL, envp);
    if(ret == -1)
        perror("execl error");
    printf("Exiting main ...\n");
    return 0;
}

hello.c

#include <unistd.h>
#include <stdio.h>
extern char** environ;

int main(void)
{
    printf("hello pid=%d\n", getpid());
    int i;
    for (i=0; environ[i]!=NULL; ++i)
    {
        printf("%s\n", environ[i]);
    }
    return 0;
}

结果:
在这里插入图片描述
确实将给定的环境变量传递过来了。

参考:
Linux execlp函数.
linux系统编程之进程(五):exec系列函数(execl,execlp,execle,execv,execvp)使用.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值