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

相关文章

linux-基础知识3

打包和压缩 zip 安装zip软件包 yum -y install zip unzip 压缩打包命令: zip -q -r -d -u 压缩包文件名 目录和文件名列表 -q:不显示命令执行过程-r:递归处理,打包各级子目录和文件-u:把文件增加/替换到压缩包中-d:从压缩包中删除指定的文件 解压:unzip 压缩包名 打包文件 把压缩包从服务器下载到本地 把压缩包上传到服务器(zip

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

【Python编程】Linux创建虚拟环境并配置与notebook相连接

1.创建 使用 venv 创建虚拟环境。例如,在当前目录下创建一个名为 myenv 的虚拟环境: python3 -m venv myenv 2.激活 激活虚拟环境使其成为当前终端会话的活动环境。运行: source myenv/bin/activate 3.与notebook连接 在虚拟环境中,使用 pip 安装 Jupyter 和 ipykernel: pip instal

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

【Linux 从基础到进阶】Ansible自动化运维工具使用

Ansible自动化运维工具使用 Ansible 是一款开源的自动化运维工具,采用无代理架构(agentless),基于 SSH 连接进行管理,具有简单易用、灵活强大、可扩展性高等特点。它广泛用于服务器管理、应用部署、配置管理等任务。本文将介绍 Ansible 的安装、基本使用方法及一些实际运维场景中的应用,旨在帮助运维人员快速上手并熟练运用 Ansible。 1. Ansible的核心概念

Linux服务器Java启动脚本

Linux服务器Java启动脚本 1、初版2、优化版本3、常用脚本仓库 本文章介绍了如何在Linux服务器上执行Java并启动jar包, 通常我们会使用nohup直接启动,但是还是需要手动停止然后再次启动, 那如何更优雅的在服务器上启动jar包呢,让我们一起探讨一下吧。 1、初版 第一个版本是常用的做法,直接使用nohup后台启动jar包, 并将日志输出到当前文件夹n

[Linux]:进程(下)

✨✨ 欢迎大家来到贝蒂大讲堂✨✨ 🎈🎈养成好习惯,先赞后看哦~🎈🎈 所属专栏:Linux学习 贝蒂的主页:Betty’s blog 1. 进程终止 1.1 进程退出的场景 进程退出只有以下三种情况: 代码运行完毕,结果正确。代码运行完毕,结果不正确。代码异常终止(进程崩溃)。 1.2 进程退出码 在编程中,我们通常认为main函数是代码的入口,但实际上它只是用户级

【编程底层思考】垃圾收集机制,GC算法,垃圾收集器类型概述

Java的垃圾收集(Garbage Collection,GC)机制是Java语言的一大特色,它负责自动管理内存的回收,释放不再使用的对象所占用的内存。以下是对Java垃圾收集机制的详细介绍: 一、垃圾收集机制概述: 对象存活判断:垃圾收集器定期检查堆内存中的对象,判断哪些对象是“垃圾”,即不再被任何引用链直接或间接引用的对象。内存回收:将判断为垃圾的对象占用的内存进行回收,以便重新使用。