linux——exec族函数

exec函数的作用:

        我们用fork函数创建新进程后,经常会在新进程中调用exec函数去执行另外一个程序。当进程调用exec函数时,该进程被完全替换为新程序。因为调用exec函数并不创建新进程,所以前后进程的ID并没有改变。

功能:

        在调用进程内部执行一个可执行文件。可执行文件既可以是一个二进制文件,也可以是任何linux下可执行的脚本文件。

函数族:

        分别是:execl,execlp,execle,execv,execvp,execvpe

函数族原型:

#include <unistd.h>
extern char **environ;

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

        execle,execvpe比较少用

返回值:

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

参数说明:

        path:可执行文件的路径名字。

        arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径必须以NULL结束

        file:如果参数file中包含/,则就将其视为路径名,否则就按PATH环境变量,在它所指定的各目录中搜寻可执行文件。

1、execl用法:

代码实例:

whereis ls:查看出ls的路径

ls: /bin/ls /usr/share/man/man1/ls.1.gz
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

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

编译运行结果:相当于成功调用ls来运行

before execl
a.out	  demo12.c  demo15.c  demo2.c  demo5.c	demo8.c  echoarg    newpro
demo10.c  demo13.c  demo18.c  demo3.c  demo6.c	demo9.c  echoarg.c
demo11.c  demo14.c  demo19.c  demo4.c  demo7.c	demo.c	 forktest

修改实现:ls -l效果

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

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

编译运行结果:

before execl
total 124
-rwxr-xr-x 1 CLC book 8481 Apr  9 20:51 a.out
-rw-r--r-- 1 CLC book  458 Apr  9 12:26 demo10.c
-rw-r--r-- 1 CLC book  457 Apr  9 16:25 demo11.c
-rw-r--r-- 1 CLC book  471 Apr  9 16:35 demo12.c
-rw-r--r-- 1 CLC book  555 Apr  9 16:46 demo13.c
-rw-r--r-- 1 CLC book  589 Apr  9 17:15 demo14.c
-rw-r--r-- 1 CLC book  444 Apr  9 17:28 demo15.c
-rw-r--r-- 1 CLC book  343 Apr  9 20:31 demo18.c
-rw-r--r-- 1 CLC book  335 Apr  9 20:41 demo19.c
-rw-r--r-- 1 CLC book  335 Apr  9 20:51 demo20.c
-rw-r--r-- 1 CLC book  160 Apr  9 00:54 demo2.c
-rw-r--r-- 1 CLC book  187 Apr  9 00:56 demo3.c
-rw-r--r-- 1 CLC book  309 Apr  9 11:43 demo4.c
-rw-r--r-- 1 CLC book  351 Apr  9 01:14 demo5.c
-rw-r--r-- 1 CLC book  277 Apr  9 01:21 demo6.c
-rw-r--r-- 1 CLC book  393 Apr  9 10:30 demo7.c
-rw-r--r-- 1 CLC book  336 Apr  9 10:51 demo8.c
-rw-r--r-- 1 CLC book  311 Apr  9 11:48 demo9.c
-rw-r--r-- 1 CLC book  161 Apr  9 00:17 demo.c
-rwxr-xr-x 1 CLC book 8381 Apr  9 17:59 echoarg
-rw-r--r-- 1 CLC book  172 Apr  9 17:59 echoarg.c
-rwxr-xr-x 1 CLC book 8536 Apr  9 11:21 forktest
-rwxr-xr-x 1 CLC book 8585 Apr  9 16:17 newpro

获取系统时间:date

CLC@Embed_Learn:~/jincheng$ date
Sun Apr  9 20:53:58 CST 2023

whereis date:查看date在哪

date: /bin/date /usr/share/man/man1/date.1.gz
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("this is system date\n");
    if(execl("/bin/date","date",NULL,NULL) == -1)
    {
        printf("execl failed!\n");      
	perror("why");
    }
    printf("after execl\n");
    return 0;
}

实现ps:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("this is system date\n");
    if(execl("/bin/ps","ps",NULL,NULL) == -1)
    {
        printf("execl failed!\n");      
	perror("why");
    }
    printf("after execl\n");
    return 0;
}

运行结果:

this is system date
  PID TTY          TIME CMD
22183 pts/1    00:00:01 bash
25728 pts/1    00:00:00 ps

2、execlp使用:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("this is system date\n");
    if(execlp("ps","ps",NULL,NULL) == -1)
    {
        printf("execl failed!\n");      
	perror("why");
    }
    printf("after execl\n");
    return 0;
}

使用execlp时,将文件路径的绝对路径去掉,依旧可以运行

p为环境变量:使用时需要调用环境变量,方法如下:

pwd:查看当前路径

echo $PATH:显示当前PATH环境变量,该变量的值由一系列以冒号分隔的目录名组成。
export PATH=$PATH:路径名:环境变量的配置

3、execvp使用:(不需要添加绝对路径)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("this is system date\n");

	char *argv[]={"ps",NULL,NULL};
    if(execvp("ps",argv) == -1)
    {
        printf("execl failed!\n");      
	perror("why");
    }
    printf("after execl\n");
    return 0;
}

编译运行结果:

this is system date
  PID TTY          TIME CMD
22183 pts/1    00:00:01 bash
25906 pts/1    00:00:00 ps
CLC@Embed_Learn:~/jincheng$ ./a.out

4、execv使用(需要添加绝对路径)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
//函数原型:int execl(const char *path, const char *arg, ...);

int main(void)
{
    printf("this is system date\n");

	char *argv[]={"ps",NULL,NULL};
    if(execv("/bin/ps",argv) == -1)
    {
        printf("execl failed!\n");      
	perror("why");
    }
    printf("after execl\n");
    return 0;
}

编译运行结果:

this is system date
  PID TTY          TIME CMD
22183 pts/1    00:00:01 bash
25940 pts/1    00:00:00 ps

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值