exec家族与system函数

exec家族函数

NAME
       execl, execlp, execle, execv, execvp, execvpe - execute a file

SYNOPSIS
       #include <unistd.h>

       extern char **environ;

       int execl(const char *pathname, const char *arg, ...
                       /* (char  *) NULL */);
       int execlp(const char *file, const char *arg, ...
                       /* (char  *) NULL */);
       int execle(const char *pathname, const char *arg, ...
                       /*, (char *) NULL, char *const envp[] */);
       int execv(const char *pathname, char *const argv[]);
       int execvp(const char *file, char *const argv[]);
       int execvpe(const char *file, char *const argv[],
                       char *const envp[]);

可以观察一些这一组函数的后缀名称,无非就是在exec函数后面加上 l,p,e,v这几个字母。

  1. l : list => 函数参数列表指定进程参数。

  1. p:path => 到PATH环境变量这个路径中查找可执行程序

  1. e:environ => 父进程提供环境变量

  1. v:数组的方式提供进程参数

进程参数

自动搜索PATH

使用当前环境变量

execl()

列表

NO

YES

execlp()

列表

YES

YES

execle()

列表

NO

NO,提供环境变量

execv()

数组

NO

YES

execvp()

数组

YES

YES

execve()

数组

NO

NO,提供环境变量

看一下demo:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc,char* argv[])
{
    char  pids[32] = {0};
    char* const ps_argv[] = {"pstree","-A","-p","-s",pids,NULL};
    char* const ps_envp[] = {"PATH=/bin:/usr/bin","TEST=Delphi",NULL};

    sprintf(pids,"%d",getpid());

    execl("/bin/pstree","pstree","-A","-p","-s",pids,NULL);
    execl("pstree","pstree","-A","-p","-s",pids,NULL);
    execle("/bin/pstree","pstree","-A","-p","-s",pids,NULL,ps_envp);
    
    execv("/bin/pstree",ps_argv);
    execvp("pstree",ps_argv);
    execve("/bin/pstree",ps_argv,ps_envp);


    return 0;
}

system函数

NAME
       system - execute a shell command

SYNOPSIS
       #include <stdlib.h>

       int system(const char *command);

参数:程序名以及进程参数(如:pstree -A -p -s $$)

返回值:进程退出状态值

下面是system(...) 函数运行原理图,和我们自己创建的create_process(...)原理差不多。

来看一下demo1:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

/*
    $$ : 表示当前进程的pid
*/

int main(int argc,char* argv[])
{
    int result = 0;

    printf("current: %d\n",getpid());

    result = system("pstree -A -p -s $$");

    printf("result = %d\n",result);

    return 0;
}

编译输出:

wj@wj:~/WORK/Learning/DT/07/07-3$ gcc test.c -o test.out
wj@wj:~/WORK/Learning/DT/07/07-3$ ./test.out 
current: 72319
systemd(1)---systemd(1454)---gnome-terminal-(2307)---bash(57230)---test.out(72319)---sh(72320)---pstree(72321)
result = 0

看一下demo2:

//test.sh

echo "Hello world from shell..."
a=1
b=1
c=$(($a+$b))
echo "c = $c"
wj@wj:~/WORK/Learning/DT/07/07-3$ chmod 777 test.sh
wj@wj:~/WORK/Learning/DT/07/07-3$ ./test.sh
Hello world from shell...
c = 2

看一下demo3:

//test.c
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>

/*
    wait: true  :代表父进程是否等待子进程结束
    wait: false :代表父进程不等待子进程结束
*/


int create_process(char* path,char* const args[],char* const env[],int wait)
{
    int ret = fork();

    if(ret == 0)
    {
        if(execve(path,args,env) == -1)
        {
            exit(-1);
        }
    }

    if(wait && ret)  // 1.wait为true。2.并且父进程是否成功创建子进程?来共同解决父进程是否等待子进程结束?
    {
        waitpid(ret,&ret,0);
    }

    return ret;   //1.如果等待,ret为子进程的退出状态;2.如果不等待,返回为子进程的pid
}


int main(int argc,char* argv[])
{
    char* target = argv[1];
    char* const ps_argv[] = {target,NULL};
    char* const ps_envp[] = {"PATH=/bin:/usr/bin","TEST=Delphi",NULL};

    int result =0;

    if(argc < 2) exit(-1);

    printf("current: %d\n",getpid());

    //result = create_process(target,ps_argv,ps_envp,1);
    result = system(target);

    printf("result = %d\n",result);
    

    return 0;
}
//helloworld.c
#include <stdio.h>

int main(int argc,char* argv[])
{
    printf("hello world\n");
    
    return 0;
}

编译运行输出:

wj@wj:~/WORK/Learning/DT/07$ gcc test.c -o test.out
wj@wj:~/WORK/Learning/DT/07$ ./test.out ./helloworld.out
current: 73126
hello world
result = 0

wj@wj:~/WORK/Learning/DT/07$ cp 07-3/test.sh ./
wj@wj:~/WORK/Learning/DT/07$ ls
07-3  helloworld.c  helloworld.out  test.c  test.out  test.sh

wj@wj:~/WORK/Learning/DT/07$ ./test.out ./test.sh
current: 73178
Hello world from shell...
c = 2
result = 0

system 和 create_process区别和联系

  1. system创建的是shell进程,功能比较强大,可以直接调用shell进程函数,但是这个功能强大(相对于我们自己创建的create_process函数来说)是以牺牲性能为代价的。

  1. 如果用 //result = create_process(target,ps_argv,ps_envp,1); 我们自己创建的create_process,则不能够调用shell进程函数。我们自己创建的create_process效率更高。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

repinkply

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值