了解C语言中的exec函数家族

(根据参考文档翻译整理而成,针对原文有补充)
    exec函数家族用新进程替换当前正在运行的进程。它可以通过使用另一个C程序来运行一个C程序,它位于头文件unistd.h下。 exec系列中有许多成员,下面以示例显示。

execvp

    execvp:使用此命令,创建的子进程不必与父进程运行相同的程序。exec类型的系统调用允许进程运行任何程序文件,其中包括二进制可执行文件或shell脚本。语法:

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

    file:表示被执行的文件的文件名
    argv:是以null结尾的字符指针数组。argv参数描述了一个或多个指向以null结尾的字符串的指针列表,这些字符串作为参数列表传递给file文件进行执行
示例1
    让我们看一个小例子,展示如何在C中使用 execvp() 函数。我们将有两个.C文件,EXEC.c和execDemo.c,并通过调用execDemo.c中的 execvp() 函数,将执行execDemo.c替换为执行EXEC.c。

//EXEC.c 
  
#include<stdio.h> 
#include<unistd.h> 
  
int main() 
{ 
    int i; 
      
    printf("I am EXEC.c called by execvp() "); 
    printf("\n"); 
      
    return 0; 
} 

    使用命令创建EXEC.c的可执行文件

gcc EXEC.c -o EXEC
//execDemo.c 
  
#include<stdio.h> 
#include<stdlib.h> 
#include<unistd.h> 
int main() 
{ 
        //A null terminated array of character  
        //pointers 
        char *args[]={"./EXEC",NULL}; 
        execvp(args[0],args); 
      
        /*All statements are ignored after execvp() call as this whole  
        process(execDemo.c) is replaced by another process (EXEC.c) 
        */
        printf("Ending-----"); 
      
    return 0; 
} 

    使用命令创建execDemo.c的可执行文件:

gcc execDemo.c -o execDemo

    使用命令./excDemo运行execDemo.c的可执行文件后,我们得到以下输出:

I AM EXEC.c called by execvp()

    编译文件execDemo.c时,一旦执行execvp(args[0],args) 语句,该程序就会被程序EXEC.c取代。之所以不会打印“ Ending-–”,是因为一旦调用 execvp() 函数,该程序就会被程序EXEC.c取代。
示例2
    execvp执行shell的示例,d.sh内容为:

#!/bin/bash
date

    test.c与d.sh在同一目录下,内容为:

#include        <stdio.h>
int main()
{
        char *arglist[]={"sh","d.sh",NULL};
        printf("begin\n");
        execvp("sh",arglist);
        printf("end\n");
}

    编译并执行,因为execvp执行d.sh后就结束了,所以并不会打印"end"。

# gcc test.c -o test
# ./test
begin
Mon Feb 15 22:30:17 CST 2021
execv

    execv:就语法而言,与 execvp() 函数非常相似。
    语法:

int execv(const char *path, char *const argv[]);

    path:指向正在被执行文件的路径
    argv[]:是以null结尾的字符指针数组
示例3
    让我们看一个小例子来说明如何在C中使用 execv() 函数。这个例子类似于上面显示的 execvp() 的例子。

//EXEC.c 
  
#include<stdio.h> 
#include<unistd.h> 
  
int main() 
{ 
    int i; 
      
    printf("I am EXEC.c called by execv() "); 
    printf("\n"); 
    return 0; 
} 

    使用命令创建EXEC.c的可执行文件:

gcc EXEC.c -o EXEC
//execDemo.c 
  
#include<stdio.h> 
#include<stdlib.h> 
#include<unistd.h> 
int main() 
{ 
        //A null terminated array of character  
        //pointers 
        char *args[]={"./EXEC",NULL}; 
        execv(args[0],args); 
      
        /*All statements are ignored after execvp() call as this whole  
        process(execDemo.c) is replaced by another process (EXEC.c) 
        */
        printf("Ending-----"); 
      
    return 0; 
} 

    使用命令创建execDemo.c的可执行文件

gcc execDemo.c -o execDemo

    使用命令./excDemo运行execDemo.c的可执行文件后,我们得到以下输出:

I AM EXEC.c called by execv()

    execvp和execv的区别,是第一个参数的不同,一个是file,一个是path,如果将示例2修改为execv的程序,test.c代码如下:
示例4

#include        <stdio.h>
int main()
{
        char *arglist[]={"sh","d.sh",NULL};
        printf("begin\n");
        execv("/bin/bash",arglist);
        printf("end\n");
}
execlp和execl

    execlp 和 execl:这两个也有相同的用途,但是它们的语法略有不同。

int execlp(const char *file, const char *arg,.../* (char  *) NULL */);
int execl(const char *path, const char *arg,.../* (char  *) NULL */);

    file:正在执行的文件的文件名
    const char *arg和省略号:描述一个或多个指向以null终止的字符串的指针的列表,这些字符串表示可用于执行的程序的参数列表。
    上面的相似的C程序可以用 execlp() 或 execl() 函数执行,它们将执行相同的任务,即用新进程替换当前进程。
示例5
    将示例2中的test.c改成execl的程序为:

#include        <stdio.h>
int main()
{
        char *arglist[]={"sh","d.sh",NULL};
        printf("begin\n");
        execl("/bin/bash",arglist[0], arglist[1], arglist[2]);
        printf("end\n");
}
execvpe和execle

    execvpe 和 execle:这两个函数也有相同的用途,但是它们的语法与上面提到的exec家族的所有成员都有点不同。

int execvpe(const char *file, char *const argv[],char *const envp[]);
int execle(const char *path, const char *arg, .../*, (char *) NULL, 
char * const envp[] */);

    上面显示的语法与所有上面的exec成员都有一个不同的参数:
    char * const envp[]:允许调用者通过参数envp指定执行程序的环境。
    envp:此参数指向以null结尾的字符串的指针数组,必须由null指针结尾。其他函数从调用进程中的外部变量environ获取新进程映像的环境。

参考文档

[1]MAZHAR IMAM KHAN.exec family of functions in C[EB/OL].https://www.geeksforgeeks.org/exec-family-of-functions-in-c/,2019-05-24.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值