Linux系统编程(再论execve)

article/2025/7/19 16:44:53

文章目录

  • 前言
  • 一、execve的第三个参数
  • 二、进程空间
  • 三、命令行参数规范
  • 四、optstring规则的扩展定义
  • 总结


前言

本篇文章我们继续来研究一下execve这个系统调用,上篇文章已经讲解了前两个参数的意义了,那么这篇文章就来讲解一下第三个参数的具体含义。

一、execve的第三个参数

execve函数的第三个参数 envp 是一个字符串数组,用于传递给新程序的环境变量。

环境变量是操作系统提供给程序的一组全局变量,用于存储与系统环境相关的配置和信息。例如,PATH 环境变量指定了可执行程序所在的路径,HOME 环境变量指定了当前用户的家目录等。程序可以通过读取环境变量来获取系统相关的配置信息以及自定义的参数。

envp 参数是一个空指针结尾的字符串数组,每个元素都是一个以 "key=value" 形式表示的环境变量设置。例如,envp 数组可以包含类似以下的元素:

envp[0] = "PATH=/usr/local/bin:/usr/bin:/bin"
envp[1] = "HOME=/home/user"
envp[2] = "LANG=en_US.UTF-8"
...
envp[n] = NULL

在程序加载执行时,新程序会继承这些环境变量的设置,并且可以通过读取它们来获取相应的环境信息。

需要注意的是,envp 数组的最后一个元素必须是 NULL,用于表示环境变量列表的结束。

使用 envp 参数,可以在调用 execve 函数时传递自定义的环境变量给新程序。这允许程序在不同的执行环境中获得不同的配置。通过修改或添加环境变量,可以对新程序的行为进行定制和调整。

例如,可以根据需要设置自定义的环境变量,然后将其作为 envp 参数传递给 execve 函数,使新程序能够感知和使用这些自定义的环境变量。这样,新程序就可以根据环境变量的设置来执行不同的逻辑或采取不同的配置。
总结:

execve 函数的第三个参数 envp 是一个字符串数组,用于传递给新程序的环境变量。它允许自定义和传递环境变量给新程序,以便在程序加载执行时进行配置和定制。

这里对程序进行改进:
fork.c:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>#define EXE "test"int main(void)
{int pid = 0;char* argv[3] = {EXE, "world", NULL};printf("begin\n");printf("now pid : %d\n", getpid());if((pid = fork()) != 0){//父进程}else{//子进程execve(EXE, argv, argv);}printf("end\n");return 0;
}

test.c:

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>int main(int argc, char** argv, char** envp)
{int i = 0;printf("argc :%d\n", argc);for(i = 0; i < argc; i++){printf("argv[%d] : %s\n", i, argv[i]);}printf("Hello World current pid :%d\n", getpid());i = 0;while(envp[i]){printf("envp[%d] :%s\n", i, envp[i]);i++;}return 0;
}

运行结果:
在这里插入图片描述
由运行结果可以看出子进程环境变量由父进程传递过来。

二、进程空间

这一张图片描述了进程的空间概要情况:
在这里插入图片描述
验证:

#include <stdio.h>
#include <malloc.h>static void Text(void)
{}int main(int argc, char** argv)
{int i = 0;int* p = (int*)malloc(4);static int uninitval;static int initval = 0;printf("argv[0] :%p\n", argv);//启动参数printf("i : %p\n", &i);//栈地址printf("p = %p\n", p);//堆地址printf("uninitval = %p\n", &uninitval);//未初始化变量printf("initval = %p\n", &initval);//初始化变量printf("Text = %p\n", Text);//代码段return 0;
}

运行结果:
在这里插入图片描述
根据运行结果可以印证上图的结果。

三、命令行参数规范

1.由选项,选项值,操作数组成

2.选项由短横线(-)开始,选项名必须是单个字母或数字字符

3.选项可以有选项值,选项与选项值之间可用空格分隔(-o test -otest)

4.如果多个选项均无选项值,可合而为一(-a-b -c-abc)

5.既不是选项,也不能作为选项值的参数是操作数

6.第一次出现的双横线(–)用于结束所有选项,后续参数为操作数

getopt函数讲解:

getopt 是一个用于解析命令行选项的函数,它是C语言中标准库 <unistd.h> 中提供的函数。

getopt 函数可以帮助程序解析命令行参数,并提供了一种方便的方式来处理选项和选项参数。它支持简化的单字符选项(短选项)以及长选项(长选项)的解析。

以下是 getopt 函数的常见参数和用法:

int getopt(int argc, char *const argv[], const char *optstring);

argc:命令行参数的数量,即 main 函数的参数 argc。

argv:命令行参数的数组,即 main 函数的参数 argv。

optstring:指定程序支持的选项字符串。

getopt 函数会迭代解析命令行参数,并返回下一个选项的字符。当解析完所有的选项后,getopt 函数返回 -1,表示解析完毕。

在循环中调用 getopt 函数,可以逐个获取命令行参数中的选项和选项参数。例如:

#include <stdio.h>
#include <unistd.h>int main(int argc, char *argv[]) {int opt;while ((opt = getopt(argc, argv, "abc:")) != -1) {switch (opt) {case 'a':printf("Option -a is set\n");break;case 'b':printf("Option -b is set\n");break;case 'c':printf("Option -c is set, value: %s\n", optarg);break;case '?':fprintf(stderr, "Unknown option: %c\n", optopt);return 1;default:break;}}for (int i = optind; i < argc; i++) {//非选项参数printf("Non-option argument: %s\n", argv[i]);}return 0;
}

以上示例代码解析了以下几种命令行参数:

单字符选项:

-a:表示选项 -a 被设置。

-b:表示选项 -b 被设置。
带参数的选项:

-c value:表示选项 -c 被设置,并且其参数为 value。
非选项参数(操作数):

通过循环使用 getopt 函数,可以依次获取每个选项及其参数,并使用 switch 语句进行处理。同时,可以在 optind 后的循环中获取非选项参数(操作数),并进行相应的处理。

需要注意的是,选项字符串中的冒号(:)可以用来指示带有参数的选项。例如,"abc:" 表示选项 -c 将带有参数。在 switch 语句中,optarg 变量用于获取选项的参数。

总结:
getopt 函数是一个用于解析命令行选项的函数。它通过遍历命令行参数,逐个解析选项和选项参数,并提供了一种方便的方式来处理命令行选项。通过了解 getopt 函数的使用方法,可以编写灵活的命令行工具,支持选项的解析和处理。

四、optstring规则的扩展定义

1.+ :将 getopt 函数的错误消息输出到 stderr(标准错误流)而不是 stdout(标准输出流)。通常情况下,错误消息会被发送到 stdout。使用 + 标志可以将错误消息重定向到 stderr,这样可以将标准输出用于其他目的。

2.- :使 getopt 函数返回一个非选项参数(即不以 - 或 – 开头的参数),作为额外的非选项参数。通常情况下,getopt 函数只返回选项字符,而将其他所有参数视为非选项参数。使用 - 标志可以将非选项参数作为额外的返回结果。

3.: :表示该选项需要一个参数。如果一个选项需要一个参数,但未提供该参数,则 getopt 函数将返回特殊值 ‘:’,并在 optopt 中存储选项字符。

#include <stdio.h>
#include <unistd.h>int main(int argc, char** argv)
{int opt = -1;while((opt = getopt(argc, argv, ":abc:")) != -1){switch (opt){case 'a':printf("Option -a is set\n");break;case 'b':printf("Option -b is set\n");break;case 'c':printf("Option -c is set, value: %s\n", optarg);break;case '?':printf("Unknow option: -%c\n", optopt);break;        default:break;}}for(int i = optind; i < argc; i++){printf("Non-option argument: %s\n", argv[i]);}return 0;
}

修改代码加上+符号,取消输出错误信息:
运行结果:
在这里插入图片描述

总结

本篇文章就讲解到这里。


http://chatgpt.dhexx.cn/article/LxmP0ZUL.shtml

相关文章

Linux0.11 execve函数(六)

系列文章目录 Linux 0.11启动过程分析&#xff08;一&#xff09; Linux 0.11 fork 函数&#xff08;二&#xff09; Linux0.11 缺页处理&#xff08;三&#xff09; Linux0.11 根文件系统挂载&#xff08;四&#xff09; Linux0.11 文件打开open函数&#xff08;五&#xff09…

C语言 execve()函数使用方法

1.君の名は execve() – 叫做执行程序函数 就像Python中的os.system(cmd)这个函数&#xff0c;我们可以用这个函数来执行我们的shell脚本&#xff0c;单独的shell命令&#xff0c;或者是调用其他的程序&#xff0c;我们的execve()这个函数就和Python中的os.system函数类似&am…

SPSS-因子分析

因子分析 有可能用较少的综合指标分析存在于各变量中的各类信息&#xff0c;而各综合指标之间彼此是不相关的&#xff0c;代表各类信息的综合指标称为因子。定义&#xff1a;因子分析就是用少数几个因子来描述许多指标或因素之间的联系&#xff0c;以较少几个因子反映原资料的 …

spss进行主成分分析

什么是主成分分析 简而概之, 就是一组数据受太多因素影响, 选出几个能代表他们的因素,并进行线性组合得到一组比原维度小的因素组合, 作为新的因素集 用spss操作 随手拿出一组数据 1.数据统一标准化 因为我们得到的原始数据大小,类型不一, 一起分析会不准确, 所以将数据全部…

实用干货!因子分析超全步骤总结

因子分析是统计数据分析方法之一&#xff0c;因子分析包括探索性因子分析和验证性因子分析。本文主要讨论探索性因子分析。 一、研究背景 关于工作满意度有14个问题&#xff0c;调研得到215份问卷结果。希望通过因子分析&#xff0c;用少量因子反映14个题目的信息&#xff0c;…

NLP | 朴素贝叶斯法的学习与分类

朴素贝叶斯法的学习与分类 《统计学习方法》李航第四章 1、概述 书上对朴素贝叶斯的描述如下&#xff1a; 朴素贝叶斯法时基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集&#xff0c;首先基于特征条件独立假设学习输入/输出的联合概率分布&#xff1b;然…

标定相机参数-张正友方法

一、实验原理 1.计算外参 设三维世界坐标的点为M=[X,Y,Z,1]T,二维相机平面像素坐标为m=[u,v,1]T,所以标定用的棋盘格平面到图像平面的单应性关系为: sm=A[R,t]M 其中 不妨设棋盘格位于Z = 0,定义旋转矩阵R的第i列为 ri, 则有: 令H=[h1 h2 h3]=λA[r1 r2 t] 于是空间到图…

《统计学习方法》——朴素贝叶斯法

引言 朴素贝叶斯法(Naive Bayes)是基于贝叶斯定理与特征条件独立假设的分类方法。朴素贝叶斯法实现简单&#xff0c;学习与预测的效率都很高&#xff0c;是一种常用的方法。 这一章需要大量的概率论知识&#xff0c;忘记了的同学建议先参阅人工智能数学基础之概率论。 朴素贝…

数据挖掘十大算法之 naïve Bayes

朴素贝叶斯法是基于贝叶斯定理和特征条件独立假设的分类方法。朴素贝叶斯法实现简单&#xff0c;学习与预测的效率都很高&#xff0c;被广泛应用于文本分类、垃圾邮件过滤、自然语言处理等场景。下面我们来介绍贝叶斯定理&#xff0c;在介绍贝叶斯定理之前&#xff0c;先介绍下…

专题:深度神经网络基本问题的原理详细分析和推导

文章目录 **写在最前面****1 神经网络算法的直观了解****1.1 神经网络过程描述**&#xff1a;**1.2 神经网络相关的几个问题****1.2.1 表征假设和激活函数** **1.2.2 结构设计(Architecture Design)****1.2.3 代价函数(Cost Function)和优化目标(Optimization objective)****1.…

第四章 朴素贝叶斯法

文章目录 朴素贝叶斯法的学习与分类基本方法数据定义学习联合概率分布如何求出条件概率分布&#xff1f;如何分类&#xff1f; 后验概率最大化的含义 朴素贝叶斯的参数估计法极大似然估计学习分类算法贝叶斯估计 朴素贝叶斯法&#xff08;与贝叶斯估计是不同的概念&#xff09;…

GAN生成对抗式神经网络数学推导

由上面一篇文章我们已经知道了&#xff0c;如果我们从真实数据分布里面取n个样本&#xff0c;根据给定样本我们可以列出其出现概率的表达式&#xff0c;那么生成这N个样本数据的似然(likelihood)就是 l ( θ ) ∏ i 1 N p ( x i ∣ θ ) l ( \theta ) \prod _ { i 1 } ^ { …

《统计学习方法》学习笔记(三)之 朴素贝叶斯法

朴素贝叶斯法 总述 朴素贝叶斯法是基于贝叶斯定理与特征条件独立性假设的分类方法。对于给定的训练数据集&#xff0c;首先基于特征独立性假设学习输入/输出的联合概率分布&#xff1b;然后基于此模型&#xff0c;对给定的输入 x x x&#xff0c;利用贝叶斯定理求出后验概率最…

朴素贝叶斯(二)|极大似然估计+学习与分类算法+贝叶斯估计| 《统计学习方法》学习笔记(十六)

朴素贝叶斯法的参数估计 1. 极大似然估计 在朴素贝叶斯法中&#xff0c;学习意味着估计 P ( Y c k ) P(Yc_k) P(Yck​)和 P ( X ( j ) x ( j ) ∣ Y c k ) P(X^{(j)}x^{(j)}|Yc_k) P(X(j)x(j)∣Yck​)。可以应用极大似然估计法估计相应的概率。先验概率 P ( Y c k ) P(Yc…

一文看懂 “极大似然估计” 与 “最大后验估计” —— 最大后验估计篇

本文历次修订后全长 2万8000余字&#xff0c;受到 CSDN 博文字数限制&#xff0c;故切分两篇发布&#xff0c;所以现在是两文看懂了… 前篇介绍参数估计背景和极大似然估计&#xff1b;本篇介绍最大后验估计和两种方法对比请务必先看前文&#xff1a;一文看懂 “极大似然估计”…

【生成模型】极大似然估计,你必须掌握的概率模型

上一期为大家说明了什么是无监督生成模型。在无监督生成模型中&#xff0c;极大似然法一直扮演着非常核心的位置&#xff0c;我们必须对它有深刻的理解&#xff0c;本期小米粥将为大家讲一下极大似然法的那些事情。 作者&编辑 | 小米粥 1 一个小游戏&#xff1a;取球猜概率…

透彻理解机器学习中极大似然估计MLE的原理(附3D可视化代码)

文章目录 相关资料一、什么是概率&#xff0c;什么是似然二、极大似然估计 Maximum Likelihood Estimation (MLE) 的含义2.1 机器学习中的极大化似然函数2.2 极大似然估计和损失函数的关系VAE最大化似然函数推导出损失函数 三、代码可视化&#xff1a;极大似然估计3.1 似然函数…

C#RSA密码以及利用欧几里得算法实现两数互质的判断

最近做课程设计,想到以前看过RSA密码的相关内容&#xff0c;于是就想用刚学的C#做一个数字加密系统。RSA加密的流程如下&#xff1a; 来看一个“玩具式”的例子&#xff1a; (1)选取两个素数p2,q11,于是N22. (2)构造数,这是小于22且不含因数2和11的自然数的个数。 (3)选一个…

判断两数互质,java实现

数组下标i和j值互质时&#xff0c;a[i][j] true,反之false Write a program to create an n * n Boolean array. If I and j are coprime, a [i] [J] is true, otherwise it is false /** * When Array index Mutuality ,a[i][j] true,else is false * 数组i和j值互质时&…

两个质数互质是_两个数互质是什么意思 如何判断

互质数为数学中的一种概念&#xff0c;即两个或多个整数的公因数只有1的非零自然数。公因数只有1的两个非零自然数&#xff0c;叫做互质数。下面是小编整理的详细内容&#xff0c;一起来看看吧&#xff01; 两个数互质是什么意思 质数为数学中的一种概念&#xff0c;即两个或多…