传奇手游风暴活动专区

  • 首页
  • 跨服动态
  • 行会战报
  • 装备图鉴
  • 2026-08-18 02:59:50

    「Linux 系统编程」exec 函数族及使用示例

    1 exec 函数族

    在 Linux 系统编程中,fork() 函数用于创建一个新的进程,这个新进程是当前进程的副本。如果我们想要新进程执行一个全新的、不同的程序,这个时候就需要用到 exec 函数族。

    exec 是 Linux 中一组功能强大且常用的函数,负责将当前进程的镜像替换为一个新的程序镜像 —— 进程的 PID 保持不变,但运行的程序被彻底替换。

    1.1 exec 函数族概览

    exec 函数族包含了多个函数,它们的核心功能相同(加载新程序),在参数传递方式上略有差异。这些函数都定义在 中。

    函数原型

    参数特点

    路径搜索

    环境变量

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

    列表 (List)

    否 (需全路径)

    继承父进程

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

    列表 (List)

    是 (PATH)

    继承父进程

    int execle(const char *path, const char *arg, ..., char *const envp[]);

    列表 (List)

    否 (需全路径)

    自定义

    int execv(const char *path, char *const argv[]);

    向量 (Vector/数组)

    否 (需全路径)

    继承父进程

    int execvp(const char *file, char *const argv[]);

    向量 (Vector/数组)

    是 (PATH)

    继承父进程

    int execvpe(const char *file, char *const argv[], char *const envp[]);

    向量 (Vector/数组)

    是 (PATH)

    自定义

    注意:execvpe 是一个 GNU 扩展,并非所有 UNIX 系统都支持(但主流 Linux 发行版都支持)。

    区分 exec 函数族每个函数:

    l (list):以列表的形式设置命令行参数

    p (path):搜索 file 时使用 path 变量

    v (vector):以数组的形式设置命令行

    e (environment):使用环境变量数组,不适用进程原有的环境变量,设置新加载程序运行的环境变量

    1.2 exec 函数参数

    const char *file / const char *path:执行的程序。如果是 file 需要借助 PATH 环境变量寻找待执行程序;如果是 path 必须是完整的路径。

    const char *arg, ...:对应的分别是命令行参数的 argv[0], argv[1], argv[2], ...,并且最后需要添加一个 NULL 表示参数结束。

    char *const argv[]:与 const char *arg, ... 同理,参数数组的最后必须以 NULL 结尾。

    1.3 exec 函数返回值

    exec 函数一旦调用成功,即执行新的程序,不返回。

    exec 只有失败才返回,返回 -1。因此通常直接在 exec 函数调用后直接调用 perror() 等错误判断。

    2 execl、execlp (参数列表形式)

    2.1 函数原型

    12int execl(const char *path, const char *arg0, const char *arg1, ..., (char *) NULL);int execlp(const char *file, const char *arg0, const char *arg1, ..., (char *) NULL);

    path/file: 要执行的程序的路径。

    execl 需要 绝对路径 或 相对路径(如 /bin/ls 或 ./my_program)。

    execlp 只需要 程序名,系统会在 $PATH 环境变量指定的目录中搜索该程序。

    arg0, arg1, ...: 命令行参数列表。arg0 是程序名本身(argv[0])。

    ...: 参数需要以 (char *) NULL 结尾,表示参数列表结束。

    2.2 代码示例

    使用 execl 执行 ls -lh

    123456789#include int main(){ execl("/bin/ls", "ls", "-l", "-h", (char*)NULL); // execl 失败才会执行后续代码 perror("execl error"); return 1;}

    使用 execlp 执行 ps aux:

    12345678910#include int main(){ // 系统会在 PATH 中找到 "ps" 命令 execlp("ps", "ps", "aux", (char*)NULL); // execlp 失败才会执行后续代码 perror("execlp failed"); return 1;}

    3 execv、execvp (参数数组形式)

    3.1 函数原型

    12int execv(const char *path, char *const argv[]);int execvp(const char *file, char *const argv[]);

    path/file: 同 execl/execlp。

    argv[]: 一个字符串指针数组,包含了所有命令行参数。该数组的最后一个元素必须是 NULL。

    3.2 代码示例

    使用 execvp 执行 ls -l /home/[username]

    123456789101112#include int main(){ // 参数数组 char* args[] = {"ls", "-l", "/home/marisa", NULL}; // 使用 execvp 执行 execvp("ls", args); perror("execvp failed"); return 1;}

    4 execle、execvpe (自定义环境变量)

    4.1 函数原型

    12int execle(const char *path, const char *arg0, ..., (char *) NULL, char *const envp[]);int execvpe(const char *file, char *const argv[], char *const envp[]);

    envp[]: 一个字符串指针数组,代表新程序的环境变量。数组以 NULL 结尾。每个字符串的格式通常是 “KEY=VALUE”。

    envp[] 为新的程序进程提供一个 完全自定义的环境,而不是继承父进程的环境。

    4.2 代码示例

    使用 execle 执行一个程序并传递自定义环境

    12345678910111213141516#include #include int main() { char* new_envp[] = { "MY_VAR=Hello_World", "PATH=/usr/bin:/bin", NULL // 环境变量数组也必须以 NULL 结尾 }; // print_env 打印环境变量 execle("./print_env", "print_env", NULL, new_envp); perror("execle failed"); return 1;}

    1234567891011121314151617181920// print_env.c#include // 外部变量 environ,它是由C库提供的指向环境变量数组的指针extern char **environ;int main(int argc, char *argv[]) { printf("Printing all environment variables:\n"); printf("===================================\n"); // 遍历环境变量数组,直到遇到NULL指针 for (char **env = environ; *env != NULL; env++) { printf("%s\n", *env); } // 也可以使用 main 的第三个参数(如果使用 execle 等方式传递了环境变量) // 但更通用的方法是使用 environ 变量 return 0;}

    print_env 程序只是打印它的所有环境变量,只会看到 MY_VAR 和 PATH,而看不到父进程原有的其他环境变量。

    5 fork() 结合 exec 调用新程序

    5.1 exec 核心特性

    exec 调用成功,当前进程的代码、数据、堆、栈等所有段都被新程序彻底覆盖。exec 之后的代码永远不会被执行(除非调用失败)。

    进程的 PID、PPID(父进程ID)、文件描述符、信号处理方式等属性会被保留。新程序可以继承父进程打开的文件、网络连接等资源。

    fork() 结合 exec 代码示例

    exec 最常见的用法是与 fork() 结合:

    父进程调用 fork() 创建子进程。

    子进程调用 exec() 来执行另一个程序。

    父进程通常调用 wait() 来等待子进程结束。

    1234567891011121314151617181920212223242526#include #include #include int main() { pid_t pid = fork(); if (pid == -1) { perror("fork failed"); return 1; } else if (pid == 0) { // 子进程 printf("I'm the child process (PID: %d).\n", getpid()); execlp("ls", "ls", "-l", NULL); // 如果 exec 失败 perror("execlp failed"); return 1; // 子进程退出 } else { // 父进程 printf("I'm the parent process (PID: %d), my child is %d.\n", getpid(), pid); wait(NULL); // 等待子进程结束 printf("Child process finished.\n"); } return 0;}

    e46宝马怎么样?
    传福音(一): 传福音的益处、方式与原则
    行会战报

    友情链接:

    ©Copyright © 2022 传奇手游风暴活动专区 All Rights Reserved.