栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 系统运维 > 运维 > Linux

Linux系统编程-Exec族函数,system函数,popen函数

Linux 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Linux系统编程-Exec族函数,system函数,popen函数

一.exec族函数

为什么要用exec族函数,有什么用

exec函数族 介绍

有时我们希望子进程去执行另外的程序,exec函数族就提供了一个在进程中启动另一个程序执行的方法。它可以根据指定的文件名或目录名找到可执行文件,并用它来取代原调用进程的数据段、代码段和堆栈段,在执行完之后,原调用进程的内容除了进程号外,其他全部被新程序的内容替换了。另外,这里的可执行文件既可以是二进制文件,也可以是Linux下任何可执行脚本文件。

在Linux中使用exec函数族主要有以下两种情况

  • 当进程认为自己不能再为系统和用户做出任何贡献时,就可以调用任何exec 函数族让自己重生。
  • 如果一个进程想执行另一个程序,那么它就可以调用fork函数新建一个进程,然后调用任何一个exec函数使子进程重生。

实际上,在Linux中并没有exec函数,而是有6个以exec开头的函数族

#include

int execl(const char *path, const char *arg, …)
int execv(const char *path, char *const argv[])
int execle(const char *path, const char *arg, …, char *const envp[])
int execve(const char *path, char *const argv[], char *const envp[])
int execlp(const char *file, const char *arg, …)
int execvp(const char *file, char *const argv[])

参数介绍:

path:指定程序的具体路径及程序名字
arg :传入给程序的参数,最后参数必须为NULL;(NULL作为参数列表的结束标记)
file:命令名
envp:环境变量参数

exec族函数参数极难记忆和分辨,函数名中的字符会给我们一些帮助:
l : 使用参数列表
p:使用文件名,并从PATH环境进行寻找可执行文件
v:应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。
e:多了envp[]数组,使用新的环境变量代替调用进程的环境变量

返回值:
  exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。


示例代码:
说明:因为是笔记,就简写了,只写了execl.execlp.execv,execvp。

//execl
#include 
#include 
#include 

int main(void)
{
    printf("before execln");
    
    if(execl("/bin/ls","ls","-l",NULL) == -1)
//  if(execl("/bin/date","date",NULL,NULL) == -1)
    {
        printf("execl failed!n");
        perror("why");
    }
    printf("after execln");
    return 0;
}
//execlp
#include 
#include 
#include 

int main(void)
{
    printf("before execln");
    
    if(execlp("ps","ps",NULL) == -1)
    {
        printf("execl failed!n");
        perror("why");
    }
    printf("after execln");
    return 0;
}
//execv
#include 
#include 
#include 

int main(void)
{
        printf("before execln");

        char *argv[] = {"/ps",NULL,NULL};

        if(execv("/bin/ps",argv) == -1)
        {
                printf("execl failed!n");
                perror("why");
        }

        printf("after execln");

        return 0;
}
//execvp
#include 
#include 
#include 

int main(void)
{
        printf("before execln");

        char *argv[] = {"ps",NULL,NULL};

        if(execvp("ps",argv) == -1)
        {
                printf("execl failed!n");
                perror("why");
        }

        printf("after execln");

        return 0;
}
execl配合fork
#include 
#include 

int main()
{
        pid_t pid;
        int data;

        while(1){
                printf("please input a data:n");
                scanf("%d",&data);
                if(data == 1){
                        pid = fork();//创建进程
                        if(pid > 0){
                                wait(NULL);
                        }else if(pid == 0){
                                execl("./textConfig","textConfig","text.config",NULL);
                        }
                }
        }
        
        return 0;
}

二.system函数 函数原型

NAME

   system - execute a shell command

SYNOPSIS

   #include 

   int system(const char *command);

返回值
如果system()在调用/bin/sh时失败则返回127,其他失败原因返回-1。若参数string为空指针(NULL),则返回非零值。如果 system()调用成功则最后会返回执行shell命令后的返回值,但是此返回值也有可能为system()调用/bin/sh失败所返回的127,因此最好能再检查errno 来确认执行成功。

#include 
#include 
#include 

int main(void)
{
    printf("before execln");
    if(system("ps") == -1)
    {
        printf("execl failed!n");      
    }
    printf("after execln");
    return 0;
}
三.popen函数 函数原型

NAME
popen, pclose - pipe stream to or from a process

SYNOPSIS
#include

   FILE *popen(const char *command, const char *type);

   int pclose(FILE *stream);

比system的好处:可以获取运行结果。
参数说明:

command: 是一个指向以 NULL 结束的 shell 命令字符串的指针。这行命令将被传到 bin/sh 并使用 -c 标志,shell 将执行这个命令。

mode: 只能是读或者写中的一种,得到的返回值(标准 I/O 流)也具有和 type 相应的只读或只写类型。如果 type 是 “r” 则文件指针连接到 command 的标准输出;如果 type 是 “w” 则文件指针连接到 command 的标准输入。

返回值:

如果调用成功,则返回一个读或者打开文件的指针,如果失败,返回NULL,具体错误要根据errno判断

int pclose (FILE* stream)

参数说明:

stream:popen返回的文件指针

返回值:

如果调用失败,返回 -1

作用:

popen() 函数用于创建一个管道:其内部实现为调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程这个进程必须由 pclose() 函数关闭。

#include 
#include 
#include 

int main(void)
{
    char ret[1024] = {0};
    FILE *fp;
    
    fp = popen("ps","r");

    int n_read = fread(ret,1,1024,fp);

    printf("reat ret %d byte,ret = %sn",n_read,ret);

    return 0;
}


运行结果:

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/827657.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号