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

execvp函数详解

In this article, we’ll take a look at using the execvp() function in C / C++.

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

In UNIX, the execvp() function is very useful if you want to run another program using our C program.

在UNIX中,如果要使用我们的C程序运行另一个程序,execvp()函数将非常有用。

NOTE: This function is applicable only to UNIX based Operating Systems. It doesn’t work on Windows

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

Let’s take a look at executing UNIX commands from our program, using illustrative examples!

让我们使用示例说明一下从程序中执行UNIX命令的方法!



execvp()的基本语法 (Basic Syntax of execvp())

This function takes in the name of the UNIX command to run, as the first argument.

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

This is there in the <unistd.h> header file, so we must include it in our program.

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


#include <unistd.h>

int execvp(const char* command, char* argv[]);

Here, we refer to a “command” as any binary executable file that is a part of the PATH environment variable. So, if you want to run custom programs, make sure that you add it to your PATH variable!

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

The second argument (argv) represents the list of arguments to command. This is an array of char* strings.

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

Here, argv contains the complete command, along with it’s arguments.

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

For example, the below array follows the format of 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);

This array MUST be NULL terminated, i.e, the last element of argv must be a NULL pointer.

该数组必须NULL终止,即argv的最后一个元素必须是NULL指针。

现在我们的C程序会怎样? (What happens to our C program now?)

This function will give the control of the current process (C program) to the command. So, the C program is instantly replaced with the actual command.

该功能将控制当前过程(C程序)到命令。 因此,C程序立即被实际命令替换。

So, anything that comes after execvp() will NOT execute, since our program is taken over completely!

因此,由于我们的程序已被完全接管,因此execvp()之后的所有内容均将execvp()执行!

However, if the command fails for some reason, execvp() will return -1.

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

So, whenever you use execvp(), if you want to maintain your C program, you generally use fork() to first spawn a new process, and then use execvp() on that new process.

因此,无论何时使用execvp() ,如果要维护C程序,通常都可以使用fork()首先产生一个新进程,然后在该新进程上使用execvp()

This is called the “fork-exec” model, and is the standard practice for running multiple processes using C.

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

Let’s now look at some examples, to understand this function better. We’ll also be using fork() along with execvp(), so that we can still have our C program with us!

现在让我们看一些示例,以更好地理解此功能。 我们还将使用fork()execvp() ,以便我们仍然可以使用C程序!

在C / C ++中使用execvp()–一些示例 (Using execvp() in C / C++ – Some Examples)

If you want to see what exactly happens if you try to use execvp() without spawning a new process using fork(). the below program shows this.

如果您想查看如果尝试使用execvp()而没有使用fork()产生新进程时发生的情况,将会发生什么。 下面的程序显示了这一点。

We’ll be executing “ls -l” from our C program.

我们将在C程序中执行“ ls -l”。

Notice that the printf() statement after execvp() is NOT executed, since the other process has taken control!

注意, 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;
}

Output

输出量


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

As you can see, the part after execvp() does not execute at all, since “ls -l” took control of our process!

如您所见, execvp()之后的部分根本不执行,因为“ ls -l”控制了我们的过程!

Let’s re-write the same example, but let’s enclose the execvp() system call inside another process, using fork().

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

Let’s see what happens now.

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


#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;
}

Output

输出量


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

If you’re in a shell, the output may look weird, but that’s because multiple processes ran in parallel! Both the outputs were indeed printed, so we’ve been able to resolve our problem.

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



结论 (Conclusion)

We learned about using the execvp() function in C / C++, to execute other programs from our C program. However, note that this will give the other program complete control of our process.

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

Due to this, we need to enclose this under another process, using the fork() system call. Hopefully, this made sense to you, and you were able to run other programs, while still being able to have control over your C program!

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

参考资料 (References)



翻译自: https://www.journaldev.com/40793/execvp-function-c-plus-plus

execvp函数详解

  • 44
    点赞
  • 111
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LINUX C函数库API 1.字符测试篇 15 1.1 15 isalnum(测试字符是否为英文或数字) 15 1.2 15 isalpha (测试字符是否为英文字母) 15 1.3 16 isascii(测试字符是否为ASCII 码字符) 16 1.4 17 iscntrl(测试字符是否为ASCII 码的控制字符) 17 1.5 17 isdigit(测试字符是否为阿拉伯数字) 17 1.6 17 isgraphis(测试字符是否为可打印字符) 17 1.7 18 islower(测试字符是否为小写字母) 18 1.8 18 isprint(测试字符是(否为可打印字符) 18 1.9 19 isspace(测试字符是否为空格字符) 19 1.10 20 ispunct(测试字符是否为标点符号或特殊符号) 20 1.11 20 isupper(测试字符是否为大写英文字母) 20 1.12 21 isxdigit(测试字符是否为16进制数字) 21 2.字符串转换篇 21 2.1 21 atof(将字符串转换成浮点型数) 21 2.2 22 atoi(将字符串转换成整型数) 22 2.3 22 atol(将字符串转换成长整型数) 22 2.4 23 gcvt(将浮点型数转换为字符串,取四舍五入) 23 2.5 24 strtod(将字符串转换成浮点数) 24 2.6 24 strtol(将字符串转换成长整型数) 24 2.7 25 strtoul(将字符串转换成无符号长整型数) 25 2.8 25 toascii(将整型数转换成合法的ASCII 码字符) 25 2.9 26 tolower(将大写字母转换成小写字母) 26 2.10 26 toupper(将小写字母转换成大写字母) 26 3.内存控制篇 27 3.1 27 calloc(配置内存空间) 27 3.2 28 free(释放原先配置的内存) 28 3.3 28 getpagesize(取得内存分页大小) 28 3.4 28 malloc(配置内存空间) 28 3.5 28 mmap(建立内存映射) 28 3.6 30 munmap(解除内存映射) 30 4.日期时间篇 31 4.1 31 asctime(将时间和日期以字符串格式表示) 31 4.2 31 ctime(将时间和日期以字符串格式表示) 31 4.3 32 gettimeofday(取得目前的时间) 32 4.4 33 gmtime(取得目前时间和日期) 33 4.5 34 localtime(取得当地目前时间和日期) 34 4.6 34 mktime(将时间结构数据转换成经过的秒数) 34 4.7 35 settimeofday(设置目前时间) 35 4.8 35 time(取得目前的时间) 35 5.内存及字符串操作篇 36 5.1 36 bcmp(比较内存内容) 36 5.2 36 bcopy(拷贝内存内容) 36 5.3 37 bzero(将一段内存内容全清为零) 37 5.4 37 index(查找字符串第一个出现的指定字符) 37 5.5. 37 memccpy(拷贝内存内容) 37 5.6 38 memchr(在某一内存范围查找一特定字符) 38 5.7 38 memcmp(比较内存内容) 38 5.8 39 memcpy(拷贝内存内容) 39 5.9 40 memmove(拷贝内存内容) 40 5.10 40 memset(将一段内存空间填入某值) 40 5.11 40 rindex(查找字符串最后一个出现的指定字符) 40 5.12 41 strcasecmp(忽略大小写比较字符串) 41 5.13 41 strcat(连接两字符串) 41 5.14 42 strchr(查找字符串第一个出现的指定字符) 42 5.15 42 strcmp(比较字符串) 42 5.16 43 strcoll(采用目前区域的字符排列次序来比较字符串) 43 5.17 43 strcpy(拷贝字符串) 43 5.18 44 strcspn(返回字符串连续不含指定字符串内容的字符数) 44 5.19 44 strdup(复制字符串) 44 5.20 45 strlen(返回字符串长度) 45 5.21 45 strncasecmp(忽略大小写比较字符串) 45 5.22 46 strncat(连接两字符串) 46 5.23 46 strncpy(拷贝字符串) 46 5.24 47 strpbrk(查找字符串第一个出现的指定字符) 47 5.25 47 strrchr(查找字符串最后出现的指定字符) 47 5.26 47 strspn(返回字符串连续不含指定字符串内容的字符数) 47 5.27 48 strstr(在一字符串查找指定的字符串) 48 5.28 48 strtok(分割字符串) 48 6. 常用数学函数篇 49 6.1 49 abs(计算整型数的绝对值) 49 6.2 49 acos(取反余弦函数数值) 49 6.3 50 asin(取反正弦函数值) 50 6.4 50 atan(取反正切函数值) 50 6.5 51 atan2(取得反正切函数值) 51 6.6 51 ceil(取不小于参数的最小整型数) 51 6.7 52 cos(取余玄函数值) 52 6.8 52 cosh(取双曲线余玄函数值) 52 6.9 53 exp(计算指数) 53 6.10 53 frexp(将浮点型数分为底数与指数) 53 6.11 54 ldexp(计算2的次方值) 54 6.12 54 log(计算以e 为底的对数值) 54 6.13 55 log10(计算以10 为底的对数值) 55 6.14 55 pow(计算次方值) 55 6.15 56 sin(取正玄函数值) 56 6.16 56 sinh(取双曲线正玄函数值) 56 6.17 56 sqrt(计算平方根值) 56 6.18 57 tan(取正切函数值) 57 6.19 57 tanh(取双曲线正切函数值) 57 7.用户组篇 58 7.1 58 endgrent(关闭组文件) 58 7.2 58 endpwent(关闭密码文件) 58 7.3 58 endutent(关闭utmp 文件) 58 7.4 59 fgetgrent(从指定的文件来读取组格式) 59 7.5 60 fgetpwent(从指定的文件来读取密码格式) 60 7.6 61 getegid(取得有效的组识别码) 61 7.7 61 geteuid(取得有效的用户识别码) 61 7.8 62 getgid(取得真实的组识别码) 62 7.9 62 getgrent(从组文件取得账号的数据) 62 7.10 63 getgrgid(从组文件取得指定gid 的数据) 63 7.11 64 getgrnam(从组文件取得指定组的数据) 64 7.12 64 getgroups(取得组代码) 64 7.13 65 getpw(取得指定用户的密码文件数据) 65 7.14 66 getpwent(从密码文件取得账号的数据) 66 7.15 67 getpwnam(从密码文件取得指定账号的数据) 67 7.16 68 getpwuid(从密码文件取得指定uid 的数据) 68 7.17 68 getuid(取得真实的用户识别码) 68 7.18 69 getutent(从utmp 文件取得账号登录数据) 69 7.19 70 getutid(从utmp 文件查找特定的记录) 70 7.20 71 getutline(从utmp 文件查找特定的记录) 71 7.21 71 initgroups(初始化组清单) 71 7.22 71 pututline(将utmp 记录写入文件) 71 7.23 72 seteuid(设置有效的用户识别码) 72 7.24 72 setfsgid(设置文件系统的组识别码) 72 7.25 73 setfsuid(设置文件系统的用户识别码) 73 7.26 73 setgid(设置真实的组识别码) 73 7.27 73 setgrent(从头读取组文件的组数据) 73 7.28 74 setgroups(设置组代码) 74 7.29 74 setpwent(从头读取密码文件的账号数据) 74 7.30 75 setregid(设置真实及有效的组识别码) 75 7.31 75 setreuid(设置真实及有效的用户识别码) 75 7.32 75 setuid(设置真实的用户识别码) 75 7.33 76 setutent(从头读取utmp 文件的登录数据) 76 7.34 76 utmpname(设置utmp 文件路径) 76 8.数据结构和算法篇 76 8.1 76 crypt(将密码或数据编码) 76 8.2 77 bsearch(二元搜索) 77 8.3 78 lfind(线性搜索) 78 8.4 79 lsearch(线性搜索) 79 8.5 80 qsort(利用快速排序法排列数组) 80 8.6 81 rand(产生随机数) 81 8.7 81 srand(设置随机数种子) 81 9 文件操作篇 82 9.1 82 close(关闭文件) 82 9.2 82 creat(建立文件) 82 9.3 83 dup(复制文件描述词) 83 9.4 83 dup2(复制文件描述词) 83 9.5 84 fcntl(文件描述词操作) 84 9.6 85 flock(锁定文件或解除锁定) 85 9.7 85 fsync(将缓冲区数据写回磁盘) 85 9.8 85 lseek(移动文件的读写位置) 85 9.9 86 mkstemp(建立唯一的临时文件) 86 9.10 86 open(打开文件) 86 9.11 88 read(由已打开的文件读取数据) 88 9.12 89 sync(将缓冲区数据写回磁盘) 89 9.13 89 write(将数据写入已打开的文件内) 89 10 文件内容操作篇 89 10.1 89 clearerr(清除文件流的错误旗标) 89 10.2 90 fclose(关闭文件) 90 10.3 90 fdopen(将文件描述词转为文件指针) 90 10.4 90 feof(检查文件流是否读到了文件尾) 90 10.5 91 fflush(更新缓冲区) 91 10.6 91 fgetc(由文件读取一个字符) 91 10.7 91 fgets(由文件读取一字符串) 91 10.8 92 fileno(返回文件流所使用的文件描述词) 92 10.9 92 fopen(打开文件) 92 10.10 93 fputc(将一指定字符写入文件流) 93 10.11 94 fputs(将一指定的字符串写入文件内) 94 10.12 94 fread(从文件流读取数据) 94 10.13 95 freopen(打开文件) 95 10.14 95 fseek(移动文件流的读写位置) 95 10.15 96 ftell(取得文件流的读取位置) 96 10.16 96 fwrite(将数据写至文件流) 96 10.17 97 getc(由文件读取一个字符) 97 10.18 97 getchar(由标准输入设备内读进一字符) 97 10.19 98 gets(由标准输入设备内读进一字符串) 98 10.20 98 mktemp(产生唯一的临时文件名) 98 10.21 99 putc(将一指定字符写入文件) 99 10.22 99 putchar(将指定的字符写到标准输出设备) 99 10.23 99 rewind(重设文件流的读写位置为文件开头) 99 10.24 99 setbuf(设置文件流的缓冲区) 99 10.25 100 setbuffer(设置文件流的缓冲区) 100 10.26 100 setlinebuf(设置文件流为线性缓冲区) 100 10.27 100 setvbuf(设置文件流的缓冲区) 100 10.28 101 ungetc(将指定字符写回文件流) 101 11 进程操作篇 101 11.1 101 atexit(设置程序正常结束前调用的函数) 101 11.2 101 execl(执行文件) 101 11.3 102 execlp(从PATH 环境变量查找文件并执行) 102 11.4 102 execv(执行文件) 102 11.5 103 execve(执行文件) 103 11.6 104 execvp(执行文件) 104 11.7 104 exit(正常结束进程) 104 11.8 104 _exit(结束进程执行) 104 11.9 105 vfork(建立一个新的进程) 105 11.10 105 getpgid(取得进程组识别码) 105 11.11 106 getpgrp(取得进程组识别码) 106 11.12 106 getpid(取得进程识别码) 106 11.13 107 getppid(取得父进程的进程识别码) 107 11.14 107 getpriority(取得程序进程执行优先权) 107 11.15 108 nice(改变进程优先顺序) 108 11.16 108 on_exit(设置程序正常结束前调用的函数) 108 11.17 109 setpgid(设置进程组识别码) 109 11.18 109 setpgrp(设置进程组识别码) 109 11.19 109 setpriority(设置程序进程执行优先权) 109 11.20 110 system(执行shell 命令) 110 11.21 110 wait(等待子进程断或结束) 110 11.22 111 waitpid(等待子进程断或结束) 111 11.23 112 fprintf(格式化输出数据至文件) 112 11.24 112 fscanf(格式化字符串输入) 112 ... ... ... ...

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值