如何在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,则输出可能看起来很奇怪,但这是因为多个进程并行运行!确实输出了两个输出,因此我们能够解决问题。