当前位置: 首页 > news >正文

exec族函数

本节学习exec族函数,并大量参考了以下链接:

linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)_云英的博客-CSDN博客

exec族函数函数的作用

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

同时,由于exec族函数包含很多API,所以一个个去Linux敲man可能有些麻烦,可以直接去Linux官网的man Page来查看:Linux man pages

 

exec族函数中的具体函数介绍

exec族函数功能

  • 在进程内部调用执行一个可执行文件。可执行文件既可以是二进制文件,也可以是任何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[]); //应用相对较少

参数说明 

  • path:可执行文件的路径名字
  • arg:可执行程序所带的参数,第一个参数为可执行文件名字,没有带路径且arg必须以NULL结束
  • file:如果参数file中包含/,则就将其视为路径名,否则就按PATH环境变量,在它所指定的各目录中搜寻可执行文件
  • 返回值:exec函数族的函数执行成功后不会返回,调用失败时,会设置errno并返回-1,然后从原程序的调用点接着往下执行

exec族函数参数极难记忆和分辨,函数名中的字符会给我们一些帮助:

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

带 “l” 的一类exec函数(l表示list)

包括execlexeclpexecle,要求将新程序的每个命令行参数都说明为 一个单独的参数。这种参数表以空指针结尾

通过execl举例:

execl.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");if(execl("./arg_go","aaa","bbb",NULL) == -1){printf("execl failed!\n");perror("why"); //用于判断错误}printf("after execl\n");return 0;
}

arg.c:

#include <stdio.h>int main(int argc,char *argv[])
{int i = 0;for(i = 0; i < argc; i++){printf("argv[%d]: %s\n",i,argv[i]); }return 0;
}

实现效果1:

可见,在运行了execl函数之后,程序确实被完全替代成了另一个程序,所以原程序最后的“after execl”并不会被打印!

同时再次强调,execl函数的第一个参数,写的是执行文件,而不是C文件,所以,运行主程序之前,先编译并自己命名一个执行文件!

那么既然execl可以使用可执行程序完全替换一段程序,那么系统的指令本质上也是一个个可执行文件,就比如经常使用的 “ls” ,通过“whereis ls”可以查看这个可执行文件的绝对路径:

修改execl.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>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;
}

实现效果2:

可见,通过execl函数,成功将原程序替换成了ls,并且还附带了“-l” 的参数

 

带 “p” 的一类exec函数

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

通过execlp举例:

execlp.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");if(execlp("ls","ls","-l",NULL) == -1){printf("execl failed!\n");perror("why");}printf("after execl\n");return 0;
}

实现效果:

可见,实现了和上面使用execl来替换“ls”相同的效果,但是代码却有所区别,execlp的第一个参数不需要输入绝对路径,只需要输入可执行文件的名字就可以,其原因就是execlp的第一个参数不是path而是file,而file参数如同上面所说: “如果参数file中包含/,则就将其视为路径名,否则就按PATH环境变量,在它所指定的各目录中搜寻可执行文件 

为了进一步对比区别,可以将execl.c的代码中的这一句进行修改,第一个参数也改成“ls”:

 if(execl("ls","ls","-l",NULL) == -1)

然后运行execl.c

 

显然,这再次说明了对于execl来说,这种直接写可执行文件名字的方式不可取

环境变量的概念穿插

另外,此处引出了“环境变量"的概念,在Linux中可以用 “echo $PATH” 来查看环境变量: 

也就是说,只要可执行文件在上图的这些环境变量路径下那么只要调用带 “p” 的exec族函数,第一个file参数就可以直接写可执行文件的名字了

Q:那如何将新的路径配置到环境变量中去?

A:使用export指令:“export PATH=$PATH:想要添加的路径

使用 “pwd” 显示当前路径:

然后使用 “export PATH=$PATH:/home/mjm/JC”  将当前路径添加到环境变量:

此时,如果修改 execlp.c 的代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");if(execlp("arg_go","aaa","bbb",NULL) == -1){printf("execl failed!\n");perror("why");}printf("after execl\n");return 0;
}

执行代码:

 

 可见,由于此时当前路径被添加到了环境变量中所以使用execlp函数并将第一个参数直接写成当前路径下的可执行文件,也可以成功运行!

带 “v” 不带 “l” 的一类exec函数 

包括execvexecvpexecve,应先构造一个指向各参数的指针数组,然后将该数组的地址作为这些函数的参数

 通过execv举例:

execv.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>int main(void)
{printf("before execl\n");char *argv[] = {"ls","-l",NULL};if(execv("/bin/ls",argv) == -1){printf("execl failed!\n");perror("why");}printf("after execl\n");return 0;
}

可见,唯一的区别就是“先构造了一个指向各参数的指针数组 

实现效果:

可见,同样实现了将“ls”替换原程序的效果,并且也增加了“-l” 的参数

 

带 “e” 的一类exec函数 (应用相对较少)

包括execleexecvpe,可以传递一个指向环境字符串指针数组的指针

由于相对比较复杂且初学时并不常用,所以不做介绍,可以去本节开头的链接去学习相关概念。

相关文章:

exec族函数

本节学习exec族函数&#xff0c;并大量参考了以下链接&#xff1a; linux进程---exec族函数(execl, execlp, execle, execv, execvp, execvpe)_云英的博客-CSDN博客 exec族函数函数的作用 我们用fork函数创建新进程后&#xff0c;经常会在新进程中调用exec函数去执行另外一个程…...

dbm与mw转换

功率值10^(dBm值/10)&#xff0c;单位mW。 对于-5dBm&#xff0c;其功率值为0.3162 mW。 dBm 10 * lg(mW&#xff09;...

【Linux】多线程之单例模式

多线程之单例模式 什么是设计模式&#xff0c;都有哪些设计模式单例模式饿汉模式懒汉模式 什么是设计模式&#xff0c;都有哪些设计模式 设计模式就是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了可重用代码、让代码更容易被他人理…...

Vision Transformer模型入门

Vision Transformer模型入门 一、Vision Transformer 模型1&#xff0c;Embedding 层结构详解2&#xff0c;Transformer Encoder 详解3&#xff0c;MLP Head 详解 二、ViT-B/16 网络结构三、Hybrid 模型详解四、ViT 模型搭建参数 一、Vision Transformer 模型 总体三个模块&am…...

如何使用 Go 获取 URL 的参数,以及使用时的问题

Go 获取 URL 参数也很容易&#xff0c;但是由于 Go 有严格的数据类型和错误管理&#xff0c;所以在使用时会些微有些复杂。所以本文不仅会讲如何获取 URL 的参数&#xff0c;也会讲在使用时的一些问题。 首先假设 URL 是https://www.example.com/?keywordabc&id12。 其他…...

Linux驱动-基于QT控制LED灯

Linux驱动-基于QT控制LED灯 环境搭建LED驱动程序基于总线设备模型基于设备树 QT界面编程测试 环境搭建 平台 韦东山100ask imax6ull pro && 大象嵌入式开发板Build Root 使用Build root编译image&#xff0c;具体配置可参考《嵌入式Linux应用开发完全手册-IMX6ULL开发…...

布隆过滤器的原理和应用场景

目录 1 原理 2 代码示例 3 位数组 4 布隆过滤器的实际应用场景 1 原理 布隆过滤器&#xff08;Bloom Filter&#xff09;是一种数据结构&#xff0c;用于快速判断一个元素是否存在于一个集合中&#xff0c;具有高效的插入和查询操作。它的设计目的是在空间效率和查询效率之…...

ElasticSearch学习

一&#xff0c;简介 ES&#xff08;elaticsearch简写&#xff09;&#xff0c; Elasticsearch是一个开源的高扩展的分布式全文检索引擎&#xff0c;它可以近乎实时的存储、检索数据&#xff1b;本身扩展性很好&#xff0c;可以扩展到上百台服务器&#xff0c;处理PB级别的数据…...

软件测试基础篇——Redis

Redis Redis数据库的配置与连接 解压redis数据库的安装包&#xff08;建议把解压后的安装包放到磁盘的根目录&#xff0c;方便访问操作&#xff09;打开【命令行窗口】&#xff1a;winR在命令行窗口&#xff0c;进入到redis安装目录中 ​ 格式一&#xff1a;cd /d redis目录…...

大数据扫盲(1): 数据仓库与ETL的关系及ETL工具推荐

在数字化时代&#xff0c;数据成为了企业决策的关键支持。然而&#xff0c;随着数据不断增长&#xff0c;有效地管理和利用这些数据变得至关重要。数据仓库和ETL工具作为数据管理和分析的核心&#xff0c;将帮助企业从庞杂的数据中提取有价值信息。 一、ETL是什么&#xff1f; …...

spring的aop动态代理对象注入时机

bean生命周期&#xff1a; bean实例化populateBean填充属性invokeAwareMethods调用aware方法postProcessBeforeInitialization后置处理器before方法initializeBean初始化beanpostProcessAfterAfterInitialization后置处理器after方法 代理对象注入有两种情况&#xff1a;提前和…...

idea集成svn

一、注意 安装svn客户端的时候一定要勾选&#xff0c;否则在idea上集成svn的时候会找不到 svn.exe 而报错。 如果当初安装时忘记勾选&#xff0c;重新运行安装包&#xff0c;选择modify&#xff0c;勾选command line client tools项中的内容。 二、配置idea集成svn 三、检出(c…...

RedisDesktopManage

RDM 简介下载安装 简介 RedisDesktopManager&#xff08;RDM&#xff09;是一个开源的跨平台图形界面工具&#xff0c;用于管理和操作 Redis 数据库。它提供了一个用户友好的界面&#xff0c;使用户能够轻松地连接、浏览、查询和修改 Redis 数据&#xff0c;而无需使用命令行界…...

《Vue.js实战》——基础篇(1)

目录 资源&#xff1a;&#x1f31f; 一、初识Vue.js&#x1f44b; Vue.js是什么&#xff1f;&#x1f647; MVVM模式 ✍ Vue.js有什么不同 ☔ 如何使用Vue.js? ☁ 传统的前端开发模式 ☀ Vue.js的开发模式 &#x1f5fb; 二、数据绑定和第一个Vue应用 &#x1f5f…...

R语言 列表中嵌套列名一致的多个数据框如何整合为一个数据框

在批量建模后容易得到list&#xff0c;list中的每个元素都是单个的tibble 或者 dataframe&#xff0c;如何将这些数据整合为一张表呢&#xff1f; 载入R包 library(broom) library(tidyverse) 模拟数据 models <- txhousing %>% group_by(city) %>% do(modlm(lo…...

PyQt5利用QTextEdit控件输入多行文本

1、总代码 #!/usr/bin/env python # -*- coding: utf-8 -*- import sys from PyQt5.QtWidgets import QApplication,QWidget from PyQt5 import QtCore, QtWidgetsclass Ui_Form(object):def setupUi(self, Form):Form.setObjectName("Form")Form.resize(320, 240)s…...

【数据结构】二叉树常见题目

文章目录 前言二叉树概念满二叉树完全二叉树二叉搜索树(二叉排序树)平衡⼆叉搜索树存储⽅式 二叉树OJ二叉树创建字符串二叉树的分层遍历1二叉树的分层遍历2给定一个二叉树, 找到该树中两个指定节点的最近公共祖先二叉树搜索树转换成排序双向链表二叉树展开为链表根据一棵树的前…...

树莓派使用 ENC28J60

前言 一些老的、Mini 的 ARM 开发板上没有预留网口&#xff0c;这样在调试升级内核或应用程序时很不方便。纵使有串口下载工具&#xff0c;但其速度也是慢地捉急。这种情况下&#xff0c;使用其它接口来扩展出一个网口无疑是一个比较好的方法。 ENC28J60 就是一个使用 SPI 接口…...

跟我学C++中级篇——模板友元的应用

一、友元 友元在以前分析过&#xff0c;而且一般编程是不推荐使用友元的&#xff0c;原因是友元破坏了类的封装性。但凡事总有例外&#xff0c;在某些情况下&#xff0c;用友元还是比较方便的&#xff0c;那么该用还得用&#xff0c;不能因噎废食。普通的友元&#xff0c;各种…...

软件测试基础篇——MySQL

MySQL 1、数据库技术概述 数据库database&#xff1a;存放和管理各种数据的仓库&#xff0c;操作的对象主要是【数据data】&#xff0c;科学的组织和存储数据&#xff0c;高效的获取和处理数据SQL&#xff1a;结构化查询语言&#xff0c;专为**关系型数据库而建立的操作语言&…...

RestClient

什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端&#xff0c;它允许HTTP与Elasticsearch 集群通信&#xff0c;而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级&#xff…...

iOS 26 携众系统重磅更新,但“苹果智能”仍与国行无缘

美国西海岸的夏天&#xff0c;再次被苹果点燃。一年一度的全球开发者大会 WWDC25 如期而至&#xff0c;这不仅是开发者的盛宴&#xff0c;更是全球数亿苹果用户翘首以盼的科技春晚。今年&#xff0c;苹果依旧为我们带来了全家桶式的系统更新&#xff0c;包括 iOS 26、iPadOS 26…...

安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件

在选煤厂、化工厂、钢铁厂等过程生产型企业&#xff0c;其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进&#xff0c;需提前预防假检、错检、漏检&#xff0c;推动智慧生产运维系统数据的流动和现场赋能应用。同时&#xff0c;…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...

MinIO Docker 部署:仅开放一个端口

MinIO Docker 部署:仅开放一个端口 在实际的服务器部署中,出于安全和管理的考虑,我们可能只能开放一个端口。MinIO 是一个高性能的对象存储服务,支持 Docker 部署,但默认情况下它需要两个端口:一个是 API 端口(用于存储和访问数据),另一个是控制台端口(用于管理界面…...

给网站添加live2d看板娘

给网站添加live2d看板娘 参考文献&#xff1a; stevenjoezhang/live2d-widget: 把萌萌哒的看板娘抱回家 (ノ≧∇≦)ノ | Live2D widget for web platformEikanya/Live2d-model: Live2d model collectionzenghongtu/live2d-model-assets 前言 网站环境如下&#xff0c;文章也主…...

深入浅出Diffusion模型:从原理到实践的全方位教程

I. 引言&#xff1a;生成式AI的黎明 – Diffusion模型是什么&#xff1f; 近年来&#xff0c;生成式人工智能&#xff08;Generative AI&#xff09;领域取得了爆炸性的进展&#xff0c;模型能够根据简单的文本提示创作出逼真的图像、连贯的文本&#xff0c;乃至更多令人惊叹的…...