在本文中,我们将了解如何在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程序!
参考文献
- C++中关于execvp()函数的LINUX手册页