【问题标题】:Difference between exec, execvp, execl, execv?exec,execvp,execl,execv之间的区别?
【发布时间】:2025-12-29 14:15:08
【问题描述】:

我正在编写一个代表 Linux 的新 shell 的代码。我想支持的命令之一是运行一个进程 例如,如果我得到以下行

command [arguments]

然后我想将command 作为一个进程运行,直到它完成运行该进程为止。

为此,我知道我需要使用 fork() 来获取子进程并获取它的 PID,我的问题是我不知道两者之间有什么区别:

execexecvpexeclexecv ...我不知道该使用哪一个以及为什么。

我当前的代码:

void External_Process(char *arguments[MAX_ARG], char* command)
{
    int pID;
    switch(pID = fork())
    {
    case -1:
        perror("fork failed");
        break;
    case 0 :
        setpgrp();

        //execv(command, arguments);
        //execvp(command, arguments);
        //execl("/bin/bash", "/bin/bash","-c",command,NULL);

        printf("smash error: > bad command %s\n" , command);
        exit(-1) ;

        break;

    default:
        return ;
    }
}

谢谢!

【问题讨论】:

标签: c linux process exec execvp


【解决方案1】:

总结:在你的情况下,我建议使用execvp

要找出exec* 函数之间的区别,您应该阅读文档:
https://linux.die.net/man/3/exec
https://linux.die.net/man/2/execve

execl*execv* 的区别在于参数传递。 execl* 需要参数列表,而 execv* 需要参数向量。
如果您在编译时知道所有参数,则参数列表很有用。在您的情况下,参数将由用户输入,并且您必须在运行时构造参数向量,因此您应该使用 execv* 函数之一。

后缀为p 的函数使用PATH 环境变量来查找程序(例如"ls"),否则您必须指定完整路径(绝对路径或相对于当前目录,例如@987654333 @)。使用PATH 是shell 通常所做的,所以这似乎是您的正确选择。

后缀为e的函数允许指定进程的环境。为简单起见,我不会在您的情况下使用它。

由此得出结论:execvp

当然,您也可以使用 system(而不是 fork/exec*/wait*),如 vladxjohn 的回答中所述,但在这种情况下,您只需使用 shell 来解释您的命令而不是实现一个基本的外壳。

【讨论】:

    【解决方案2】:

    尝试阅读手册:https://linux.die.net/man/3/execv

    摘录:

    说明 exec() 系列函数用新的进程映像替换当前进程映像。本手册页中描述的函数是 execve(2) 的前端。 (有关替换当前进程映像的更多详细信息,请参见 execve(2) 的手册页。)

    这些函数的初始参数是要执行的文件的名称。

    execl()、execlp() 和 execle() 函数中的 const char *arg 和后续省略号可以被认为是 arg0、arg1、...、argn。它们一起描述了一个或多个指向以空字符结尾的字符串的指针列表,这些字符串表示已执行程序可用的参数列表。按照惯例,第一个参数应该指向与正在执行的文件关联的文件名。参数列表必须以 NULL 指针终止,并且由于这些是可变参数函数,因此该指针必须强制转换 (char *) NULL。

    execv()、execvp() 和 execvpe() 函数提供了一个指向以 null 结尾的字符串的指针数组,这些字符串表示新程序可用的参数列表。按照惯例,第一个参数应该指向与正在执行的文件关联的文件名。指针数组必须以 NULL 指针终止。

    execle() 和 execvpe() 函数允许调用者通过参数 envp 指定执行程序的环境。 envp 参数是一个指向以 null 结尾的字符串的指针数组,并且必须由 NULL 指针终止。其他函数从调用进程中的外部变量 environ 获取新进程映像的环境。

    execlp() 和 execvp() 的特殊语义

    如果指定的文件名不包含斜杠 (/) 字符,则 execlp()、execvp() 和 execvpe() 函数会复制 shell 在搜索可执行文件时的操作。在 PATH 环境变量中指定的以冒号分隔的目录路径名列表中查找该文件。如果未定义此变量,则路径列表默认为当前目录,后跟 confstr(_CS_PATH) 返回的目录列表。 (此 confstr(3) 调用通常返回值“/bin:/usr/bin”。)

    【讨论】:

      【解决方案3】:

      在 C 中,您可以使用“系统”命令。 这将执行您作为函数参数输入的内容。

      这是一个例子:

      system("ls -l");
      

      如果您想获取输出,您可以重定向到其他来源。

      【讨论】: