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;
}
相关推荐
且从容.2 小时前
Ubuntu安装flume
linux·ubuntu·flume
承渊政道2 小时前
Linux网络学习【Reactor反应堆模式】
linux·网络·学习·ubuntu·reactor
且从容.5 小时前
ubuntu安装flink
linux·ubuntu·flink
爱和冰阔落6 小时前
【Linux网络】TCP 服务器如何并发处理多个客户端?从 fork、僵尸进程到双重 fork
linux·运维·服务器·网络
程序员沉梦听雨6 小时前
WSL2的安装与使用
linux·wsl
微小的鱼7 小时前
Linux的渲染与显示系统链路
android·java·linux
lisanmengmeng7 小时前
alertmanger 标签 rules 打上分组标签
linux·运维·服务器
Android系统攻城狮8 小时前
Linux FFmpeg深度解析之av_write_frame调用流程与实战(三十三)
linux·运维·服务器·ffmpeg·音视频进阶·ffmpeg音视频
Linux-lucky19 小时前
45-Linux学习之旅之防火墙与WEB加固
linux·前端·网络·学习·ubuntu
禁默20 小时前
启元 Q1 二次开发实践:Ubuntu 部署与仿真验证,从 PrimeConsole 到 ROS 2 Humble + RViz
linux·运维·ubuntu