如何在 C/C++ 中使用 execvp() 函数

在本文中,我们将了解如何在C/C++中使用execvp()函数。

在Unix中,如果您希望使用我们的C程序运行另一个程序,则execvp()函数非常有用。

:此功能仅适用于基于UNIX的操作系统。在Windows上不起作用

让我们使用说明性的例子来看看如何从我们的程序中执行UNIX命令!


execvp()的基本语法

该函数接受要运行的UNIX命令的名称作为第一个参数。

它位于<unistd.h>头文件中,因此我们必须将其包含在我们的程序中。

1#include <unistd.h>
2
3int execvp(const char* command, char* argv[]);

这里,我们将命令称为任何二进制可执行文件,它是PATH环境变量的一部分。因此,如果您想运行定制程序,请确保将其添加到您的PATH变量中!

第二个参数(argv)表示Command的参数列表。这是一个char* 字符串数组。

这里,argv包含完整的命令及其参数。

例如,下面的数组遵循argv的格式。

1char* argument_list[] = {"ls", "-l", NULL}; // NULL terminated array of char* strings
2
3// Ok! Will execute the command "ls -l"
4execvp("ls", argument_list);

这个数组 必须NULL结尾,即argv的最后一个元素必须是NULL指针。

我们的C程序现在怎么了?

该函数将当前进程(C程序)的控制权交给命令。因此,C程序立即被实际的命令替换。

所以,execvp()后面的任何东西都不会执行,因为我们的程序已经完全接管了!

但是,如果由于某种原因命令失败,execvp()将返回-1。

因此,每当您使用execvp()时,如果您想维护您的C程序,通常首先使用fork()产生一个新进程,然后在该新进程上使用execvp()

这称为fork-exec模型,是使用C运行多个进程的标准实践。

现在让我们看一些例子,以更好地理解这个函数。我们还将使用fork()execvp(),这样我们仍然可以使用C程序!

在C/C++中使用execvp()-一些示例

如果您想知道如果您尝试使用execvp()而不使用fork()产生一个新进程,究竟会发生什么。下面的程序显示了这一点。

我们将从C程序中执行ls-L

注意,没有执行execvp()之后的printf()语句,因为另一个进程已经控制了!

 1#include <stdio.h>
 2#include <unistd.h>
 3
 4int main() {
 5    char* command = "ls";
 6    char* argument_list[] = {"ls", "-l", NULL};
 7
 8    printf("Before calling execvp()\n");
 9
10    // Calling the execvp() system call
11    int status_code = execvp(command, argument_list);
12
13    if (status_code == -1) {
14        printf("Process did not terminate correctly\n");
15        exit(1);
16    }
17
18    printf("This line will not be printed if execvp() runs correctly\n");
19
20    return 0;
21}

输出

1Before calling execvp()
2total 3
3-rwxrwxrwx 1 user user 22088 May 30 16:37 a.out
4-rwxrwxrwx 1 user user 16760 May 30 16:37 sample
5-rw-rw-rw- 1 user user 1020 May 30 16:37 sample.c

如您所见,execvp()后面的部分根本不会执行,因为ls-L控制了我们的进程!

让我们重写相同的示例,但让我们使用fork()execvp()系统调用包含在另一个进程中。

让我们看看现在会发生什么。

 1#include <stdio.h>
 2#include <unistd.h>
 3
 4int main() {
 5    char* command = "ls";
 6    char* argument_list[] = {"ls", "-l", NULL};
 7
 8    printf("Before calling execvp()\n");
 9
10    printf("Creating another process using fork()...\n");
11
12    if (fork() == 0) {
13        // Newly spawned child Process. This will be taken over by "ls -l"
14        int status_code = execvp(command, argument_list);
15
16        printf("ls -l has taken control of this child process. This won't execute unless it terminates abnormally!\n");
17
18        if (status_code == -1) {
19            printf("Terminated Incorrectly\n");
20            return 1;
21        }
22    }
23    else {
24        // Old Parent process. The C program will come here
25        printf("This line will be printed\n");
26    }
27
28    return 0;
29}

输出

1Before calling execvp()
2Creating another process using fork()...
3This line will be printed
4user@shell:$ total 3
5-rwxrwxrwx 1 user user 22088 May 30 16:37 a.out
6-rwxrwxrwx 1 user user 16760 May 30 16:37 sample
7-rw-rw-rw- 1 user user 1020 May 30 16:37 sample.c

如果您在一个外壳中,输出可能看起来很奇怪,但这是因为多个进程并行运行!两个输出确实都打印出来了,所以我们已经能够解决我们的问题了。


结论

我们了解了如何在C/C++中使用execvp()函数来执行C程序中的其他程序。但是,请注意,这将使另一个程序完全控制我们的进程。

因此,我们需要使用fork()系统调用将其包含在另一个进程中。希望这对您是有意义的,并且您能够运行其他程序,同时仍然能够控制您的C程序!

参考文献


Published At
Categories with 技术
Tagged with
comments powered by Disqus