深入了解Linux系统—— 环境变量

命令行参数

我们知道,我们使用的指令它本质上也是一个程序,我们要执行这个指令,输入指令名然后回车即可执行;但是对于指令带选项,又是如何实现的呢?

问题:main函数有没有参数?

在我们之前写代码的时候,我们知道main函数是程序的入口;但是操作系统在执行程序之前,会先执行一个入口函数(_start),然后由这个入口函数去调用我们的main函数。

那我们的main函数到底有没有参数?答案是有的。

我们先来看下面运行程序的现象:

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

在这里插入图片描述

这里,我们在命令行中打开某个可执行程序,后面跟上选项(指令 -选项);

可以看到在main函数中我们是可以访问命令行输入的内容的(命令行参数)。

main函数的参数都有哪些内容呢?

  • argc:命令行参数的个数
  • argv:命令行参数的内容(char*类型的数组,最后以NULL结尾)
  • env:环境变量表(在文章后面内容中详细讲解)。

在这里有一个疑问,我们在命令行输入的内容是如何转化成argv表,并传递给main函数的呢?

这个就比较简单了,我们在命令行中输入的内容,由我们的命令行解释器bash对这些内容进行拆分,然后形成命令行参数表(argv)和参数的个数argc

然后再通过调用等一系列操作(bash创建子进程,通过execve系统调用)将参数传递给main函数。

简单来说,就是命令行解释器(bash)对我们命令行内容进行拆分,然后形成命令行参数个数argc和命令行参数列表argv

在这里插入图片描述

所以,有了命令行参数列表,我们程序就可以实现不同的子功能(命令 + 选项的实现原理)

环境变量

在了解环境变量之前,先思考一个问题,为什么在执行我们自己写的程序时就要带路径,而使用指令程序时就不用带路径?

我们想要运行一个程序,首先要先找到这个程序(bash去找)

这个问题就很简单了,我们的指令程序都在/usr/bin目录下,而我们的程序不在usr/bin目录下。

但是,为什么在usr/bin路径下的程序,在执行时不需要带路径?

  • 环境变量一般指操作系统中用来指定操作系统运行环境的一些参数。
  • 例如:我们在写的C/C++代码,在链接的时候,我们不知道所链接的动静态库在哪里,但是依然可以链接成功生成可执行程序,其原因就是:有关环境变量帮助编译器进行查找
  • 环境变量通常具有某些特殊用途,在操作系统中通常具有全局性

查看环境变量

  • 查看所有环境变量:env
  • 查看一个环境变量:ench $环境变量名

在这里插入图片描述

设置环境变量

export

我们现在能够看到环境变量了,我们可不可以修改环境变量?当然是可以的

export新增环境变量

我们可以使用export指令来新增一个新的环境变量,具体语法如下:

export name=val

在这里插入图片描述

export除了新增一个环境变量,我们还可以使用它来修改一个已经存在的环境变量的值。

在这里插入图片描述

这里如果进行了上述修改,我们的大部分指令都无法使用了,因为在当前PATH路径下,bash找不到可执行程序。

但是存在一些还可以使用的指令,因为这些指令是bash进程自己执行的,比如export

在本篇文章后序内容详细叙述

unset

我们可以新增一个环境变量,那我们可不可以删除一个环境变量?当然也是可以的

unset指令可以删除一个环境变量,用法如下:

unset name

在这里插入图片描述

常见的环境变量

PATH

PATH环境变量,它指的是命令的搜索路径;

为什么在usr/bin路径下的程序,在执行时不需要带路径?

我们要运行一个程序,首先要找到它,所以我们自己写的程序运行时需要带路径;

而在usr/bin路径下的指令程序不需要带路径,这是因为存在环境变量PATH帮助bash去查找执行程序。

在这里插入图片描述

所以,当我们把我们自己写的程序所在的路径加入到PATH中,或者将我们的可执行程序放到/usr/bin目录下,我们运行我们自己写的程序就也不需要带路径了。

这里就不演示了,感兴趣的可以去尝试一下

HOME

Linux中,当我们执行cd ~指令时,我们会进入当前用户的家目录;但是,操作系统是如何知道我们当前用户的家目录呢?

这里就直接说了:存在一个环境变量HOME;当我们执行cd ~时,bash就会在环境变量表中查找HOME,然后进行到HOME加目录中。

在这里插入图片描述

此外,root用户的家目录和普通用户的家目录还是存在一定差别的

在这里插入图片描述

SHELL

SHELL环境变量,它表示当前的shell,也就是当前使用的命令行解释器;

一般情况下是/bin/bash

在这里插入图片描述

更多的环境变量

除了上述的环境变量,还存在非常多的环境变量,这里简单了解一下

在这里插入图片描述

  • HOSTNAME:当前系统的主机名
  • HISTSIZEbash记录历史指令的个数
  • SSH_TTY:当前通过SSH会话链接终端设备的路径
  • PWD:表示当前路径
  • USER:当前用户的登录名
  • LOGNAME:可以理解为和user一样
  • _:表示上次路径

获取环境变量

在上述中,讲述了使用envecho $查看环境变量,那我们现在想要通过写代码时获取环境变量该如何去做呢?

main函数参数

在上面叙述main函数参数时,提到main函数还存在第三个参数env,我们就可以通过这个参数来获取环境变量

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

在这里插入图片描述

系统调用

main函数第三个参数env它是环境变量参数表,我们查看起来不是很方便;

我们可以通过系统调用来在代码中获取环境变量的值:

getenv

在这里插入图片描述

getenv,我们把要查看环境变量的名字传参给getenv函数,它会返回我们查询环境变量的值。

#include<stdio.h>
#include<stdlib.h>
int main()
{printf("%s\n",getenv("PATH"));return 0;
}

在这里插入图片描述

putenv对于这个函数,这里就先不叙述,在后序文章中再详细讲解。

通过第三方变量获取

libc在定义着一个全局变量environ,它始终指向当前的环境变量表;

它不存在于任何头文件,我们在使用它时,需要使用extern声明。

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

在这里插入图片描述

执行程序,我们可以发现依然可以获取全部的环境变量。

此外,父进程的环境变量可以被子进程继承;就比如父进程bash创建我们的子进程时,

理解环境变量

要理解环境变量,这里我们先思考一个问题,环境变量存储在哪里?

在执行一个程序时,首先要找到到这一个程序,那谁去找呢?

答案是bash去找,通过环境变量PATH去找,在bash中存储着一份环境变量表;

现在又存在一个问题,当我们修改环境变量以后,退出登录,再次登录时我们会发现环境变量又变为修改前的值了。

所以环境变量最开始是存储在哪里呢?

答案:在系统的配置文件中

那我们现在是不是就可以这样去理解了:在我们每次登录时,操作系统为我们创建一个bash,再将环境变量表拷贝一份到bash中;这样我们每次登录bash中都存在一份环境变量表。

环境变量特性

  • 环境变量通常具有全局属性,可以被子进程继承下去。

环境变量表

在上诉代码中,我们无论是使用main函数参数env还是全局指针变量environ进行访问全局变量是时,循环条件写的都是env[i]!=NULL/environ[i]!=NULL

这是因为,环境变量表它本质上就是一个指针数组,数组最后以NULL结尾。

在这里插入图片描述

补充

本地变量

在操作系统中除了环境变量之外,还存在着本地变量;

就比如我们在命令行直接输入i=1,这样我们使用env查看环境变量时是查看不到i的;但是我们可以使用echo $i来查看变量i的值。

在这里插入图片描述

env是查看所有的环境变量,而如果我们想要查看所有的本地变量,就要使用set,它能显示出所有的环境变量和本地变量;当然我们也可以使用echo $查看某一个变量的值。

这里可能感觉怪怪的,为什么要存在本地变量呢?

  1. 作用域限制
    本地变量仅在当前Shell会话或函数内部有效,不会传递给子进程或其他Shell环境。这种隔离性避免了变量被意外修改或污染其他进程的运行环境。
  2. 临时数据存储
    适用于临时存储中间计算结果或循环控制变量(如计数器),用完即弃,无需长期保留,简化资源管理。
  3. 安全性增强
    若变量包含敏感信息(如临时密钥),使用本地变量可防止其被子进程继承,降低数据泄露风险。
  4. 避免命名冲突
    在脚本或函数中使用本地变量(如通过local关键字声明),能隔离同名变量的影响,提升代码的模块化和可维护性。

以博主现在的认知,简单理解就是为了满足bash的语法

内建命令

这个问题在上面简单描述了,我们的环境变量是存在于bash中的,因为我们所有执行的程序都是bash去执行的,bash需要这些环境变量来完成执行我们的程序;

在修改PATH时,我们发现一个问题,将PATH修改之后,一部分指令不能执行了,但是一部分指令是可以执行的,这是为什么呢?

这里简单解释一下:

我们可以将指令分为两部分:

  • 普通命令:bash通过创建子进程,然后让子进程去执行;
  • 内建命令:bash自己通过函数调用或者系统调用去完成,不需要创建子进程。

这里内建命令像export就是bash自己直接去完成的,我们就是修改了PATH对它是没有影响的,所以它可以执行;

到这里本篇文章内容大致就结束了,感谢支持

简单总结:

  1. 了解命令行参数,理解main函数是三个参数
  2. 环境变量,查看env/echo、设置环境变量export
  3. 了解常见的环境变量
  4. 通过main函数参数、系统调用、environ获取环境变量
  5. 理解环境变量具有全局性、环境变量表的结构
  6. 简单了解本地变量和内建命令

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/79626.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pip安装包时网络不畅,替换国内PyPI镜像源

1、PyPI 镜像源 1.1、定义 PyPI 镜像源是对 Python Package Index&#xff08;PyPI&#xff09;官方仓库的复制。 PyPI 是 Python 社区中最大的软件包仓库&#xff0c;存储着大量的 Python 包&#xff0c;供开发者们下载和使用。 然而&#xff0c;由于 PyPI 服务器位于国外&a…

贪心算法解决会议安排问题

文章目录 前言 一、什么是贪心算法&#xff1f; 贪心算法的基本概念&#xff1a;贪心算法并不从整体最优上加以考虑&#xff0c;所做的选择只是在某种意义上的局部最优选择。 二、会议安排题目 1.题目理解 2.思路剖析 总结 前言 本文将主要介绍贪心算法需要注意的地方以…

从入门到登峰-嵌入式Tracker定位算法全景之旅 Part 4 |IMU 死算与校正:惯性导航在资源受限环境的落地

Part 4 |IMU 死算与校正:惯性导航在资源受限环境的落地 本章聚焦 ESP32-S3 平台上如何利用 LSM6DS3 IMU 实现 死算(Dead Reckoning),并结合 零速更新(ZUPT) 或 磁力计辅助 进行 漂移校正,最终通过 EKF/UKF 融合提升定位精度。 一、传感器简介与校准 LSM6DS3 主要参数 加速…

力扣1128题解

记录 2525.5.4 题目&#xff1a; 思路&#xff1a; 先将dominoes[i]的二元全部变为前大后小的形式&#xff0c;再遍历该数组&#xff0c;用数组来记录。 代码&#xff1a; class Solution {public int numEquivDominoPairs(int[][] dominoes) {int [] [] cnt new int [10…

with的用法

Python SQLite 操作详解 本文档详细解释了使用 Python 操作 SQLite 数据库时涉及的关键概念和代码实践&#xff0c;包括 with 语句、事务处理、批量插入以及相关的优化建议。 一、with 语句的作用&#xff08;自动关门的保险库&#xff09; with sqlite3.connect(city_1301.d…

力扣解题汇总(困难)

文章目录 技巧42_接雨水 技巧 42_接雨水 class Solution {public int trap(int[] height) {int LMax 0, RMax 0;int len height.length;int[] L2R new int[len];int[] R2L new int[len];//计数每一个格的左右边最高柱for (int i 0; i < len; i) {LMax Math.max(LMa…

【Redis】Redis常用命令

4.Redis常见命令 4.1 Redis数据结构介绍 Redis是一个key-value的数据库&#xff0c;key一般是String类型&#xff0c;不过value的类型多种多样&#xff1a; 命令太多&#xff0c;不需要死记&#xff0c;学会查询就好了~ Redis为了方便我们学习&#xff0c;将操作不同数据类型…

Ubuntu 系统上广受好评的浏览器推荐

日常使用与开发者首选 Firefox 特点&#xff1a;开源、隐私保护强大&#xff0c;支持丰富扩展&#xff08;如开发者工具、广告拦截&#xff09;&#xff0c;默认预装且跨平台兼容368。 适用场景&#xff1a;日常浏览、开发者调试&#xff08;支持实时 CSS/JS 编辑&#xff09;、…

Rust Trait 学习

概述 特征&#xff08;trait&#xff09;是rust中的概念&#xff0c;类似于其他语言中的接口&#xff08;interface&#xff09;。特征定义了一个可以被共享的行为&#xff0c;只要实现了特征&#xff0c;你就能使用该行为。 如果不同的类型具有相同的行为&#xff0c;那么我们…

JavaScript性能优化实战(9):图像与媒体资源优化

引言 在当今视觉驱动的网络环境中,图像和媒体资源往往占据了网页总下载量的60%-80%,因此对图像和媒体资源进行有效优化已成为前端性能提升的关键领域。尽管网络带宽持续提升,但用户对加载速度的期望也在不断提高,特别是在移动设备和网络条件不稳定的场景下。 本文作为Jav…

NHANES指标推荐:LC9

文章题目&#xff1a;Association between lifes crucial 9 and kidney stones: a population-based study DOI&#xff1a;10.3389/fmed.2025.1558628 中文标题&#xff1a;生命的关键 9 与肾结石之间的关联&#xff1a;一项基于人群的研究 发表杂志&#xff1a;Front Med 影响…

谷歌 NotebookLM 支持生成中文播客

谷歌 NotebookLM 支持生成中文播客。 2025 年 4 月 29 日&#xff0c;NotebookLM 宣布其 “音频概览”&#xff08;Audio Overviews&#xff09;功能新增 76 种语言支持&#xff0c;其中包括中文。用户只需将文档、笔记、研究材料等上传至 NotebookLM&#xff0c;然后在设置中选…

ElasticSearch深入解析(十):字段膨胀(Mapping 爆炸)问题的解决思路

文章目录 一、核心原理&#xff1a;动态映射的双刃剑1. 动态映射的工作机制2. 映射爆炸的触发条件3. 底层性能损耗 二、典型场景与案例分析1. 日志系统&#xff1a;动态标签引发的灾难2. 物联网数据&#xff1a;设备属性的无序扩展 三、系统性解决方案1. 架构层优化2. 配置层控…

交互式智能体面临长周期决策和随机环境反馈交互等挑战 以及解决办法

交互式智能体面临长周期决策和随机环境反馈交互等挑战 以及解决办法 目录 交互式智能体面临长周期决策和随机环境反馈交互等挑战 以及解决办法随机初始化参数,lora但是训练需要更加细粒度的评价指数(对思考过程评价,对得出结果的证明评价,对结果评价)用户进看到结果《RAGE…

4:机器人目标识别无序抓取程序二次开发

判断文件是否存在 //判断文件在不在 int HandEyeCalib::AnsysFileExists(QString FileAddr) {QFile File1(FileAddr);if(!File1.exists()){QMessageBox::warning(this,QString::fromLocal8Bit("提示"),FileAddrQString::fromLocal8Bit("文件不存在"));retu…

【Touching China】2007-2011

文章目录 1、20072、20083、20094、20105、2011 1、2007 钱学森 身份&#xff1a;中国航天事业奠基人&#xff0c;中国科学院、中国工程院资深院士获奖事迹&#xff1a;钱学森1955年冲破重重阻力回到祖国&#xff0c;长期担任火箭导弹和航天器研制的技术领导职务。他以总体、动…

linux常用基础命令_最新版

常用命令 查看当前目录下个各个文件大小查看当前系统储存使用情况查看当前路径删除当前目录下所有包含".log"的文件linux开机启动jar更改自动配置文件后操作关闭自启动linux静默启动java服务查询端口被占用查看软件版本重启关机开机启动取别名清空当前行创建文件touc…

Mamba+Attention+CNN 预测模型:破局长程依赖的计算机视觉新范式

目录 一、引言:从 CNN 到 Mamba 的视觉建模进化之路 二、模型关键组成部分解析 (一)CNN 基干:局部特征提取器 (二)Mamba 块:长程依赖建模核心 (三)注意力机制:特征交互增强器 三、模型创新点 四、模型原理与作用 五、优缺点对比 六、应用领域 一、引言:从 C…

LangChain4j +DeepSeek大模型应用开发——8 Function Calling 函数调用

Function Calling 函数调用也叫 Tools 工具 入门案例 例如&#xff0c;大语言模型本身并不擅长数学运算。如果应用场景中偶尔会涉及到数学计算&#xff0c;我们可以**为他提供一个 “数学工具”。**当我们提出问题时&#xff0c;大语言模型会判断是否使用某个工具。 创建工具…

【Prometheus-Mongodb Exporter安装配置指南,开机自启】

目录 内容概述 一、创建MongoDB监控专用用户二、安装MongoDB Exporter三、启动Exporter服务四、配置Systemd服务五、服务管理命令六、Prometheus集成配置七、Grafana看板 内容概述 本教程详细演示了如何在Linux系统中部署MongoDB Exporter以监控MongoDB数据库&#xff0c;并将…