P11 Linux进程编程exec族函数

2023-12-10 14:52
文章标签 linux 函数 编程 进程 exec p11

本文主要是介绍P11 Linux进程编程exec族函数,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言    

                  

🎬 个人主页:@ChenPi

🐻推荐专栏1: 《Linux C应用编程(概念类)_@ChenPi的博客-CSDN博客》✨✨✨ 

🔥 推荐专栏2: 《C++_@ChenPi的博客-CSDN博客》✨✨✨

🛸推荐专栏3: ​​​​​​《链表_@ChenPi的博客-CSDN博客 》 ✨✨✨
🌺本篇简介  :  Linux进程在运行中我们如何进入到另一个进程呢?

                         我们可以使用exec系统调用

Linux 是一个多用户多任务的操作系统,每个用户可以同时运行多个程序

进程是程序运行的主体,包括进程的创建,调度和消亡的整个过程

当用户执行一个指令或者启动一个程序时,就创建了一个进程

一个运行的程序也可能有多个进程。

每个进程将被分配各种资源    

一 exec族函数

1.1 exec族函数函数的作用:

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

1.2 exec函数族分别是:execl, execlp, execle, execv, execvp, execvpe
函数原型:

#include <unistd.h> extern char **environ; int execl(const char *path, const char *arg, ... /* (char *) NULL */); 
int execlp(const char *file, const char *arg, ... /* (char *) NULL */); 
int execle(const char *path, const char *arg, ... /*, (char *) NULL, 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[]); 
  • 返回值:
  • exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行。
  • 参数说明:
  • path:可执行文件的路径名字
  • arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
  • file:如果参数file中包含/,则就将其视为路径名,否则就按 PATH环境变量,在它所指定的各目录中搜寻可执行文件。

1.3 exec族函数的区别  

1.3.1 execl()和 execv()的区别

execl()和 execv()都是基本的 exec 函数,都可用于执行一个新程序,它们之间的区别在于:

参数格式不同,参数 path 意义和格式都相同,指向新程序的路径名,既可以是绝对路径、也可以是相对路径。execl()和 execv()不同的在于第二个参数,execv()的argv 参数与 execve()的 argv 参数相同,也是字符串指针数组;而 execl()把参数列表依次排列,使 用可变参数形式传递,本质上也是多个字符串,以 NULL 结尾,如下所示:

// execv 传参 
char *arg_arr[5]; 
/*参数 argv 则指定了传递给新程序的命令行参数。是一个字符串数组,
该数组对应于 main(int argc, char *argv[])函数的第二个参数 argv,
且格式也与之相同,是由字符串指针所组成的数组,以 NULL 结束。*/argv[0]对应的便是新程序自身路径名。 
arg_arr[0] = "./newApp"; 
arg_arr[1] = "Hello"; 
arg_arr[2] = "World"; 
arg_arr[3] = NULL; 
execv("./newApp", arg_arr); // execl 传参 
execl("./newApp", "./newApp", "Hello", "World", NULL); 

1.3.2 execlp()和 execvp()的区别

execlp()和 execvp()在 execl()和 execv()基础上加了一个 p,这个 p 其实表示的是 PATH;execl()和execv()要求提供新程序的路径名,而 execlp()和 execvp()则允许只提供新程序文件名,系统会在由 环境变量 PATH 所指定的目录列表中寻找相应的可执行文件,如果执行的新程序是一个 Linux 命 令,这将很有用;当然,execlp()和 execvp()函数也兼容相对路径和绝对路径的方式。

1.3.1 execle()和 execve()的区别

execle()和 execvpe()这两个函数在命名上加了一个 e,这个 e 其实表示的是 environment 环境变量, 意味着这两个函数可以指定自定义的环境变量列表给新程序,参数envp与系统调用execve()的envp参数相同,也是字符串指针数组,使用方式如下所示:

// execvpe 传参 
char *env_arr[5] = {"NAME=app", "AGE=25", "SEX=man", NULL}; 
char *arg_arr[5]; arg_arr[0] = "./newApp"; 
arg_arr[1] = "Hello"; 
arg_arr[2] = "World";
arg_arr[3] = NULL;
execvpe("./newApp", arg_arr, env_arr); // execle 传参 
execle("./newApp", "./newApp", "Hello", "World", NULL, env_arr); 

二 exec族函数使用示例

6 个 exec 库函数运行 ls 命令,并加入参数-li。

2.1 execl

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>void main()
{char ret = execl("/bin/ls","ls","-li",NULL);if(-1 == ret)  //调用失败返回-1perror("");
}

2.2 execv

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>void main()
{char *canshu[] = {"ls","-li",NULL};execv("/bin/ls",canshu);
}

2.3 execlp

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>void main()
{execlp("ls","ls","-li",NULL);
}

2.4 execvp

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>void main()
{char *canshu[] = {"ls","-li",NULL};execvp("ls",canshu);
}

2.5 execle

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
char *env_init[] = {"AA=aa","BB=bb",NULL};  //作为参数传到下个执行文件void main()
{execle("./test","test",NULL,env_init);}

2.6 execve

#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>void main()
{char *env_init[] = {"AA=aa","BB=bb",NULL};  //作为参数传到下个执行文件char *canshu[] = {"test","-li",NULL};execve("./test",canshu,env_init);}

 2.7 总结: 

  • l : 使用参数列表
  • p:使用文件名,并从PATH环境进行寻找可执行文件
  • v:应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数。
  • e:多了envp[]数组,使用新的环境变量代替调用进程的环境变量

这篇关于P11 Linux进程编程exec族函数的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/477414

相关文章

快速修复一个Panic的Linux内核的技巧

《快速修复一个Panic的Linux内核的技巧》Linux系统中运行了不当的mkinitcpio操作导致内核文件不能正常工作,重启的时候,内核启动中止于Panic状态,该怎么解决这个问题呢?下面我们就... 感谢China编程(www.chinasem.cn)网友 鸢一雨音 的投稿写这篇文章是有原因的。为了配置完

Python的time模块一些常用功能(各种与时间相关的函数)

《Python的time模块一些常用功能(各种与时间相关的函数)》Python的time模块提供了各种与时间相关的函数,包括获取当前时间、处理时间间隔、执行时间测量等,:本文主要介绍Python的... 目录1. 获取当前时间2. 时间格式化3. 延时执行4. 时间戳运算5. 计算代码执行时间6. 转换为指

Python正则表达式语法及re模块中的常用函数详解

《Python正则表达式语法及re模块中的常用函数详解》这篇文章主要给大家介绍了关于Python正则表达式语法及re模块中常用函数的相关资料,正则表达式是一种强大的字符串处理工具,可以用于匹配、切分、... 目录概念、作用和步骤语法re模块中的常用函数总结 概念、作用和步骤概念: 本身也是一个字符串,其中

Python如何精准判断某个进程是否在运行

《Python如何精准判断某个进程是否在运行》这篇文章主要为大家详细介绍了Python如何精准判断某个进程是否在运行,本文为大家整理了3种方法并进行了对比,有需要的小伙伴可以跟随小编一起学习一下... 目录一、为什么需要判断进程是否存在二、方法1:用psutil库(推荐)三、方法2:用os.system调用

Linux命令之firewalld的用法

《Linux命令之firewalld的用法》:本文主要介绍Linux命令之firewalld的用法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux命令之firewalld1、程序包2、启动firewalld3、配置文件4、firewalld规则定义的九大

Java程序进程起来了但是不打印日志的原因分析

《Java程序进程起来了但是不打印日志的原因分析》:本文主要介绍Java程序进程起来了但是不打印日志的原因分析,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录Java程序进程起来了但是不打印日志的原因1、日志配置问题2、日志文件权限问题3、日志文件路径问题4、程序

Linux之计划任务和调度命令at/cron详解

《Linux之计划任务和调度命令at/cron详解》:本文主要介绍Linux之计划任务和调度命令at/cron的使用,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录linux计划任务和调度命令at/cron一、计划任务二、命令{at}介绍三、命令语法及功能 :at

Linux下如何使用C++获取硬件信息

《Linux下如何使用C++获取硬件信息》这篇文章主要为大家详细介绍了如何使用C++实现获取CPU,主板,磁盘,BIOS信息等硬件信息,文中的示例代码讲解详细,感兴趣的小伙伴可以了解下... 目录方法获取CPU信息:读取"/proc/cpuinfo"文件获取磁盘信息:读取"/proc/diskstats"文

Linux内核参数配置与验证详细指南

《Linux内核参数配置与验证详细指南》在Linux系统运维和性能优化中,内核参数(sysctl)的配置至关重要,本文主要来聊聊如何配置与验证这些Linux内核参数,希望对大家有一定的帮助... 目录1. 引言2. 内核参数的作用3. 如何设置内核参数3.1 临时设置(重启失效)3.2 永久设置(重启仍生效

kali linux 无法登录root的问题及解决方法

《kalilinux无法登录root的问题及解决方法》:本文主要介绍kalilinux无法登录root的问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,... 目录kali linux 无法登录root1、问题描述1.1、本地登录root1.2、ssh远程登录root2、