如何在C/C++中使用execvp()函数
在本文中,我们将介绍如何在C/C++中使用execvp()函数。
在UNIX中,如果要使用我们的C程序运行另一个程序,execvp()函数将非常有用。
说明:此功能仅适用于基于UNIX的操作系统。
在Windows上不起作用
让我们看一下示例,从程序中执行UNIX命令!
execvp()的基本语法
此函数将要运行的UNIX命令的名称作为第一个参数。
该文件位于<unistd.h>头文件中,因此我们必须将其包含在程序中。
#include <unistd.h> int execvp(const char* command, char* argv[]);
其中我们将"命令"称为" PATH"环境变量一部分的任何二进制可执行文件。
因此,如果要运行自定义程序,请确保将其添加到PATH变量中!
第二个参数(" argv")表示"命令"的参数列表。
这是一个char *字符串数组。
其中argv包含完整的命令及其参数。
例如,以下数组遵循" argv"的格式。
char* argument_list[] = {"ls", "-l", NULL}; //NULL terminated array of char* strings
//Ok! Will execute the command "ls -l"
execvp("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()语句没有执行!
#include <stdio.h>
#include <unistd.h>
int main() {
char* command = "ls";
char* argument_list[] = {"ls", "-l", NULL};
printf("Before calling execvp()\n");
//Calling the execvp() system call
int status_code = execvp(command, argument_list);
if (status_code == -1) {
printf("Process did not terminate correctly\n");
exit(1);
}
printf("This line will not be printed if execvp() runs correctly\n");
return 0;
}
输出
Before calling execvp() total 3 -rwxrwxrwx 1 user user 22088 Jan 30 16:37 a.out -rwxrwxrwx 1 user user 16760 Jan 30 16:37 sample -rw-rw-rw- 1 user user 1020 Jan 30 16:37 sample.c
如您所见,execvp()之后的部分根本不执行,因为" ls -l"控制了我们的过程!
让我们重写相同的示例,但使用fork()将execvp()系统调用包含在另一个进程中。
让我们看看现在会发生什么。
#include <stdio.h>
#include <unistd.h>
int main() {
char* command = "ls";
char* argument_list[] = {"ls", "-l", NULL};
printf("Before calling execvp()\n");
printf("Creating another process using fork()...\n");
if (fork() == 0) {
//Newly spawned child Process. This will be taken over by "ls -l"
int status_code = execvp(command, argument_list);
printf("ls -l has taken control of this child process. This won't execute unless it terminates abnormally!\n");
if (status_code == -1) {
printf("Terminated Incorrectly\n");
return 1;
}
}
else {
//Old Parent process. The C program will come here
printf("This line will be printed\n");
}
return 0;
}
输出
Before calling execvp() Creating another process using fork()... This line will be printed user@shell:$total 3 -rwxrwxrwx 1 user user 22088 Jan 30 16:37 a.out -rwxrwxrwx 1 user user 16760 Jan 30 16:37 sample -rw-rw-rw- 1 user user 1020 Jan 30 16:37 sample.c
如果您使用的是Shell,则输出可能看起来很奇怪,但这是因为多个进程并行运行!确实输出了两个输出,因此我们能够解决问题。

