exev函数族

一.exev函数族

1.1功能

exec()函数族的主要功能是在当前进程中运行一个新的程序。使用这些函数可以实现以下功能:

  1. 程序替换(Program Replacement):调用exec()函数后,当前进程的代码和数据会被新程序的代码和数据替换。这可以用于动态加载和替换程序,使得一个进程可以切换到运行不同的程序,实现灵活的程序执行。

  2. 命令行参数传递:exec()函数族提供了不同的方式传递命令行参数给新程序。可以使用列表或数组形式将参数传递给新程序。同时,还可以在某些函数中使用可 参数。

  3. 环境变量传递:部分exec()函数族提供了传递环境变量的功能。可以通过字符串数组形式设置新程序的环境变量。

  4. 程序搜索和执行:一些exec()函数(如execvp()execlp())会自动搜索可执行文件的路径,无需指定完整路径。它们会根据环境变量PATH中指定的路径,搜索并执行指定的程序。

  5. 进程间传递状态信息:通过执行新程序,可以将一些状态信息以特定的方式传递给新程序。这样可以在进程间共享数据和状态,并实现进程间的通信。

需要注意的是,exec()函数族在成功执行后,不会返回到原来的程序。新程序的代码开始执行,原来的进程被完全替换。因此,通常在exec()函数调用后紧跟exit()函数,以确保原来的程序在替换后退出。

1.2函数原型

exec()函数族的函数原型如下:

  1. int execl(const char *path, const char *arg0, ... /*, (char *)0 */);

    • path:要执行的可执行文件的路径。
    • arg0:可执行文件的名称,作为参数传递给新程序。
    • 可变参数:新程序的命令行参数,以空指针(char *)0结尾。
  2. int execv(const char *path, char *const argv[]);

    • path:要执行的可执行文件的路径。
    • argv:新程序的命令行参数,以字符串数组形式传递,其中第一个字符串是可执行文件的名称。
  3. int execle(const char *path, const char *arg0, ... /*, (char *)0, char *const envp[] */);

    • path:要执行的可执行文件的路径。
    • arg0:可执行文件的名称,作为参数传递给新程序。
    • 可变参数:新程序的命令行参数,以空指针(char *)0结尾。
    • envp:新程序的环境变量,以字符串数组形式传递。
  4. int execvp(const char *file, char *const argv[]);

    • file:要执行的可执行文件的名称,不包含路径。
    • argv:新程序的命令行参数,以字符串数组形式传递,其中第一个字符串是可执行文件的名称。
  5. int execve(const char *file, char *const argv[], char *const envp[]);

    • file:要执行的可执行文件的路径。
    • argv:新程序的命令行参数,以字符串数组形式传递。
    • envp:新程序的环境变量,以字符串数组形式传递。

这些函数返回值为-1表示执行出错。成功执行exec()函数后,当前进程的代码和数据将被新程序的代码和数据替换,并开始执行新程序。

1.3后缀含义

exec()函数族有一些不同的后缀,用于表示不同的功能和参数形式。下面是一些常见的后缀:

  1. l:表示使用列表(list)形式的参数。接收一系列用空格分隔的命令行参数作为参数传递给新程序。

  2. v:表示使用数组(vector)形式的参数。接收一个字符串数组作为参数传递给新程序,其中包含程序名称和命令行参数。

  3. p:表示通过路径(path)搜索程序。会根据环境变量PATH中指定的路径搜索并执行指定的程序。

  4. e:表示接收环境变量(environment)参数。可以指定新程序运行时的环境变量,以字符串数组形式传递。

  5. x:表示接收完整的参数列表。除了接收程序路径和命令行参数外,还可以指定新程序运行时的环境变量。

这些后缀可以结合使用,来达到所需的功能和参数形式。例如,execlp()函数接收一个程序名称和一系列的命令行参数,并会在PATH环境变量指定的路径中搜索该程序进行执行。

需要注意的是,exec()函数族中并没有具有无后缀的exec()函数,因为这样的函数原则上无法确定参数列表的长度。所以,我们需要使用带有具体后缀的函数来适应不同的参数形式和需求。

1.4函数案例

execl:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    printf("This is the original program\n");
    
    // 使用execl函数族调用ls命令
    execl("/bin/ls", "ls", "-l", NULL);
    
    printf("This line will not be executed\n");
    
    return 0;
}

execlp:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    printf("This is the original program\n");
    
    // 使用execl函数族调用ls命令
    execlp("ls", "ls", "-l", NULL);
    
    printf("This line will not be executed\n");
    
    return 0;
}

execv:

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    printf("This is the original program\n");
    char *buf[]={ "ls", "-l", NULL};
    // 使用execl函数族调用ls命令
    execv("/bin/ls",buf);
    
    printf("This line will not be executed\n");
    
    return 0;

}

exeve

cpp 复制代码
#include <stdio.h>
#include <unistd.h>

int main() {
    char *args[] = { "/path/to/my_executable", "arg1", "arg2", NULL };
    char *env[] = { "ENV_VAR1=value1", "ENV_VAR2=value2", NULL };
    
    printf("This is the original program\n");
    
    // 使用execve函数族执行自定义可执行文件,并传递环境变量
    execve("/path/to/my_executable", args, env);
    
    printf("This line will not be executed\n");
    
    return 0;
}
相关推荐
颇有几分姿色3 分钟前
深入理解 Linux 内存管理:free 命令详解
linux·运维·服务器
AndyFrank33 分钟前
mac crontab 不能使用问题简记
linux·运维·macos
筱源源1 小时前
Kafka-linux环境部署
linux·kafka
算法与编程之美1 小时前
文件的写入与读取
linux·运维·服务器
xianwu5432 小时前
反向代理模块
linux·开发语言·网络·git
Amelio_Ming2 小时前
Permissions 0755 for ‘/etc/ssh/ssh_host_rsa_key‘ are too open.问题解决
linux·运维·ssh
Ven%3 小时前
centos查看硬盘资源使用情况命令大全
linux·运维·centos
TeYiToKu4 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
dsywws4 小时前
Linux学习笔记之时间日期和查找和解压缩指令
linux·笔记·学习
yeyuningzi4 小时前
Debian 12环境里部署nginx步骤记录
linux·运维·服务器