环境变量概念详解!(4千字长文)

news2025/1/24 8:45:17

环境变量!

文章目录

  • 环境变量!
    • 环境变量
      • PATH
        • export
          • export的错误用法
      • 定义命令行变量
      • 环境变量哪里来的
      • 其他各种环境变量
        • HOME
        • HOSTNAME
        • LOGNAME
        • HISTSIZE
      • PWD
    • 环境变量相关指令
      • echo
      • env
      • getenv——相关函数!
      • export
      • set
      • unset
    • 命令行参数
      • argc
      • argv
      • envp
        • environ
      • putenv

环境变量

我们是否可以认为我们平时写的程序是一个指令呢?可以的!

其实我们平时写的程序和我们在linux下执行的指令是同一个东西!

image-20221218120056463

都是可执行程序!

那为什么我们执行的时候,需要用到./xxx这样来执行我们的程序,但是使用系统里面的指令就只要输入就可以呢?

image-20221218141601462

我们从报错我们就可以看出要执行一个程序,就要先找到这个指令!

而 ./ 就是当前路径!通过这个系统找到我们程序的!

所以有两种方法来使我们的程序变的像指令一样使用

  1. 将我们的程序拷贝在==/usr/bin/这个路径下!——但是不建议因为我们的程序没有经过测试,没有经过测试的程序最好不要安装在系统里面!会污染指令池拷贝就是linux的安装!==image-20221218142521259
  2. 修改环境变量——PATH

PATH

PATH是系统中的一个环境变量!操作系统在启动的时候会在shell的上下文之中给我们定义的一个环境变量!是全局有效!

echo PATH//这样查看是不行的!
echo $PATH//这样才能正确查看!

image-20221218143216709

我们可以看到里面有很多的路径!每个路径都按照 : 来分隔开来!

而操作系统在执行指令的时候就是在这些路径下面!来一个个的检索对应的指令!如果指令存在运行!如果不存在就报错!

所以我们只要让我们的路径添加到PATH里面就可以像系统指令一样的去使用了!而且还不会影响指令池!

export

export就是一个用来专门修改环境变量的指令!

export的错误用法
export PATH=xxxxx//指某个路径

这样写会发生什么事情?

会导致这个环境变量下面的所有路径被这个路径给覆盖了!image-20221218144610245

所以绝不可以怎么写,这样还会导致所有的指令都失效了!

image-20221218144649189

不过解决的方法也很简单重启一下就好了,因为这只是一个内存级的环境变量

定义命令行变量

linux的命令行解释器是可以定义命令行式的变量,环境变量也是属于这的一种!

image-20221218145543115

image-20221218145932009

环境变量其实很好理解

我们要明白shell本质也是一个进程!

我们以前在写c/c++程序的时候!我们会去使用new/malloc来申请空间!

new/malloc就是在进程运行的时候申请空间的!

也就是说进程在运行期间是可以对它的空间进行动态的调整的!

有了空间就可以存储数据!环境变量本质也是一个数据!就是一个字符串!

所以在命令行上面定义环境变量其实也是差不多的效果!就是申请空间将数据保存起来!

环境变量哪里来的

上面我们说到PATH这个环境变量重启之后就可以恢复!但是是根据什么来恢复的?

答案是在用户的工作目录下面的两个文件!

image-20221218150345091

我们进入.bash_profile里面看

image-20221218150538906

里面开始就是一个shell脚本 —— 当前工作路径下.bashrc如果存在就执行它

然后里面也定义了一个环境变量 然后导环境变量!

image-20221218150743034

.bashrc里面的内容也是相似的!会先去检查系统/etc路径里面的bashrc会不会存在存在会去执行它!

image-20221218150945768

而这个系统bashrc里面会会存在很多的动作用来构建环境变量!

vim /etc/bashrc //用vim进行查看!

而系统每次启动就会把当前工作路径下的bash_profile执行一次,将环境变量导入当前的shell中!

所以内存中就会存在一个PATH,即使我们将它覆盖了下一次系统启动后也会重新根据这个生成出来!

这种具有全局属性和特殊功能的变量我们称为环境变量!——也可以怎么说环境变量就是操作系统为了满足不同的应用场景而预先在系统内设置的一堆全局变量!

就是有各种各样的环境变量!操作系统才能完成各种各样的功能!所以才需要开始就预先设置好!

其他各种环境变量

HOME

这个环境变量就是当前用户的工作目录!

image-20221218151759817

所以我们使用 **~**的时候本质就是进入$HOME所对应的路径下!

cd ~
cd $HOME//这个和上面的结果是一样的!都是切换到当前的工作目录!

HOSTNAME

这个环境变量对应的是主机名

image-20221218152028702

LOGNAME

这个是对应的这个系统的用户名!

image-20221218152041143

HISTSIZE

image-20221218152230127

当我们在命令行按上下的时候,就会显示出以前的历史的指令!

这个就是就是可以记录的历史命令的数量!

PWD

这个环境变量记录着我们的当前路径!

image-20221219171410241

当我们的路径改变的时候!bash也会跟着修改PWD的这个环境变量的值!

我们调用ls指令 我们查看当前路径下的时候都是直接后面跟文件名的!

ls test.c

例如上面这样!而其实ls是通过调用PWD这个环境变量用来知道我们所处的路径的!

环境变量相关指令

echo

显示环境变量的值!

echo $xxx// xx就是环境变量的名称!

env

用看查看所有的环境变量!

image-20221218152455884

这些都是系统里面的环境变量!

getenv——相关函数!

这是一个函数专门用来获取环境变量的!

image-20221218164326316

这是一个用来专门获取环境变量的C语言函数接口!

返回值是个该变量的指针!如果找不到就返回一个null

使用

#include <stdio.h>    
#include <stdlib.h>    
#include <string.h>    
#define USER "USER"    
int main()    
{    
 char* who = getenv(USER);    
 if(strcmp(who,"root")== 0)                              
 {     
     printf("user:%s\n",who);    
     printf("user:%s\n",who);    
     printf("user:%s\n",who);    
     printf("user:%s\n",who);    
     printf("user:%s\n",who);    
 }    
 else{    
     printf("权限不足!\n");    

 }    
 return 0;    
}  

USER的环境变量的最大意义就在于可以识别当前linux用户!

linux的很多指令都是通过USER来识别的!

image-20221218170148261

export

用来修改环境变量!

也可将命令行的上定义的本地变量变成环境变量!

我们可以用以下代码来验证

#include <stdio.h>    
#include <stdlib.h>    
#include <string.h>    
#define USER "USER"    
#define MY_ENV "myval"    
int main()    
{    
    char *myenv = getenv(MY_ENV);    
    if(myenv == NULL)    
    {    
        printf("%s,not found\n", MY_ENV);    
        return 1;    
    }    
    printf("%s = %s\n",MY_ENV,myenv); 
}

image-20221219163603131

我们可以发现是找不到!

但是如果我们使用

export myval
export myval=1000//也可以这样定义的时候导

image-20221219164318129

我们上面说过!bash本质是一个进程!而mycmd本质也是一个进程!是bash的子进程!

通过的是fork函数来实现的!

而我们的环境变量是定义在bash这个进程上的!

但是我们的子进程也可以识别到这个环境变量!——这个说明全局变量,具有全局属性的根本就是环境变量会被子进程给继承下去的!

为什么要继承下去?

为了适应不用的应用场景!

像是我们使用cd这个切换指令!当我们不是root用户的时候想要切换到home目录下的其他用户的路径的时候!我们就会被告知权限不足!cd指令本质也是一个子进程!就是通过继承读取USER这个环境变量来做身份认证的!

而区别的本地变量!(还没有用exprot导入的)就只在当前的进程(bash)下面有效!

set

即显示本地变量!又显示环境变量!将所有的变量显示出来!

image-20221219170358573

unset

取消环境变量!

image-20221219170638567

这样环境变量就被我们取消了

取消本地变量!

image-20221219170945608

命令行参数

我们使用的main()函数虽然我们一般都是这样使用的!

但是main函数本质也是有参数的!一共有三个

int main(int argc ,char* argv,char* envp[]);

那么这三个参数分别有什么用吗?

argc

argc相当于是第二个数组的大小!

argv

而且我们都知道main函数是一个主函数!那么是谁调用了main函数? ——是操作系统!

==argv是一个指针数组!==那么重点来了?那它的值是谁传的?——就是操作系统/父进程

那传的是什么呢?

我们可以测试一下!

#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;
}

image-20221219214525816

我们可以看到argv数组的内容其实就是命令行上的内容!——命令行上的内容都是要传给argv的!

第一个就是程序名!剩下的都是选项!

同理我们使用的一些指令!例如 ls都是一样的!ls -a -l 这个会被传入到ls这个程序里面的argv数组!

image-20221219215547672

这个工作是由shell和操作系统一起完成实现的!

那么这个参数的最大的意义是什么呢?

假如我们以后写一个程序 想要让这个程序根据不同点选项执行程序内不同的功能的时候!那么这个参数就会发挥用处了!(例如ls 我们可以在后面跟上 -a,-l之类的选择让它执行不同的功能!)

举个例子

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc,char* argv[])
{
    if(argc != 2)
    {
        printf("Usage: \n\t%s [-a/-b/-ab/-ac/-bc/abc]\n",argv[0]);
        return 1;
    }
    if(strcmp("-a",argv[1])== 0)
    {
        printf("功能a\n");
    }
    if(strcmp("-b",argv[1])== 0)
    {
        printf("功能b\n");
    }
    if(strcmp("-c",argv[1])== 0)
    {                                                                                   
        printf("功能c\n");
    }    
    if(strcmp("-ab",argv[1])== 0)
    {
        printf("功能ab\n");  
     }
    if(strcmp("-bc",argv[1])== 0)
    {
        printf("功能bc\n");
    }
    return 0;
}

image-20221220102141491

例如在ls下面执行不同的打印就是通过命名行参数!来读取继承获得的!

envp

也是一个指针数组!

只不过它指向的是一个个的环境变量!结尾也是NULL

环境变量的就是一行行的字符串!

所以其实当main函数被调用的时候!如何带有这些参数!

那么系统就会自动的生成两张表!一个是命令行参数表!一个是环境变量表!

每个进程都会生成!

这就是为什么进程可以拿到环境变量的原因!

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

image-20221220104958608

我们发现所有的环境变量全都都导入到了这个进程里面!

image-20221220105008877

我们发现我们导入的环境变量也可以被传进入!

environ

如果我们既不想用环境变量参数envp也不想使用getenv话C语言还为我们提供了一个参数让我们来使用!

image-20221220105730042

这是一个全局变量的二级指针!这个指针本质其实就是指向envp这张表上使用这个参数前面要加上extren

我们可以通过这来访问环境变量!

因为数组传参的时候会发生降维,会降维成只想内部元素类型的指针!

所以envp发生降维就是内部元素是char*型,那么降维就是char**

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

image-20221220110834541

这样我们就有在我们进程的上下文中获取环境变量的三种方式!

  1. getenv——函数!
  2. envp参数!
  3. environ——二级指针!

不过我们一般都是使用getenv更多!

putenv

image-20221220111442137

putenv是改变或者添加一个环境变量!

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

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

相关文章

stata绘图指令

stata绘图指令 – 潘登同学的stata笔记 文章目录stata绘图指令 -- 潘登同学的stata笔记绘图概览韦恩图折线图连线图线性拟合图直方图函数图添加特殊字符和文字绘图概览 Stata 提供的图形种类&#xff1a; twoway 二维图scatter 散点图line 折线图area 区域图lfit 线性拟合图q…

漏洞扫描工具AWVS的安装及配置使用过程

简介 Acunetix Web Vulnerability Scanner&#xff08;AWVS&#xff09;可以扫描任何通过Web浏览器访问和遵循HTTP/HTTPS规则的Web站点。适用于任何中小型和大型企业的内联网、外延网和面向客户、雇员、厂商和其它人员的Web网站。 AWVS可以通过检查SQL注入攻击漏洞、XSS跨站脚…

LinuxGUI自动化测试框架搭建(三)-虚拟机安装(Hyper-V或者VMWare)

&#xff08;三&#xff09;-虚拟机安装&#xff08;Hyper-V或者VMWare&#xff09;1 Hyper-V安装1.1 方法一&#xff1a;直接启用1.2 方法二&#xff1a;下载安装1.3 打开Hyper-V2 VMWare安装注意&#xff1a;Hyper-V或者VMWare只安装一个&#xff0c;只安装一个&#xff0c;只…

SQL——34道经典例题之1-17

目录 1 查询每个部门最高薪水的人员名称 2 查询哪些人的薪水在部门平均薪水之上 3 查询每个部门的平均薪水等级 3.1 每个部门的平均薪水的等级 3.2 每个部门的平均的薪水等级 4 查询最高薪水&#xff08;不用max函数&#xff09; 5 查询平均薪水最高的部门的部门编号 …

FE_CSS CSS 的三大特性

1 层叠性 相同选择器给设置相同的样式&#xff0c;此时一个样式就会覆盖&#xff08;层叠&#xff09;另一个冲突的样式。层叠性主要解决样式冲突的问题 层叠性原则&#xff1a; 样式冲突&#xff0c;遵循的原则是就近原则&#xff0c;哪个样式离结构近&#xff0c;就执行哪个…

「C/C++」C/C++预处理器

博客主页&#xff1a;何曾参静谧的博客 文章专栏&#xff1a;「C/C」C/C学习 目录一、宏替换 #define1. 定义常量2. 定义函数3. 定义代码块二、条件编译 #if1. 使用 #ifdef 和 #endif 编译不同平台的代码2. 使用 #if 和 #else 编译不同版本的代码3. 使用 #ifndef 和 #define和#…

机器学习 00 交叉验证

一、什么是交叉验证(cross validation) 交叉验证:将拿到的训练数掘&#xff0c;分为训练和验证集。以下图为例: 将数据分成4份&#xff0c;其中一份作为验证集。然后经过4次(组)的测试&#xff0c;每次都更换不同的验证集。即得到4组模型的结果&#xff0c;取平均值作为最终结…

ENVI 5.6软件安装教程

软件下载 [软件名称]&#xff1a;ENVI 5.6 [软件大小]&#xff1a;3.25G [安装环境]&#xff1a;Win7~Win11或更高 软件介绍 ENVI 5.6是一款实现遥感图像处理的工具&#xff0c;已经广泛应用于科研、环境保护、气象、石油矿产勘探、农业、林业、医学、地球科学、公用设施管…

RK3568平台使用PyQt5遇到的_ZTI18QOpenGLTimeMonitor, version Qt_5问题解决

1、背景 由于开发需要在ubuntu 20.04 RK3568平台上面使用PyQt5来运行GUI软件&#xff0c;整个软件的环境如下&#xff1a;python3.8 PyQt5 5.14.1版本 fireflyfirefly:/usr/bin$ pip list Package Version ---------------------- -------------------- blink…

4.基于多目标粒子群算法冷热电联供综合能源系统运行优化

4.基于多目标粒子群算法冷热电联供综合能源系统运行优化《文章复现》 相关资源代码&#xff1a;基于多目标粒子群算法冷热电联供综合能源系统运行优化 基于多目标算法的冷热电联供型综合能源系统运行优化 考虑用户舒适度的冷热电多能互补综合能源系统优化调度 仿真平台:matl…

微信小程序【TypeError:Cannot read property ‘xxx‘ of undefined】特殊情况解决方法

xxx是一个属性 报错&#xff1a; 解决方法 翻译&#xff1a;TypeError&#xff1a;无法读取未定义的属性“ xxx” 产生原因&#xff1a; 未定义对应的属性变量不能正确的找到对应的变量 解决方法&#xff1a; 原因一&#xff1a; 在data中定义对应变量&#xff0c;并且最…

【51单片机】:定时器的详解(包括对单片机定时解释、各类定时方式,以及中断方式)

学习目标&#xff1a; 51定时/计数器的详解。 码字不易&#xff0c;如有帮助请收藏&#xff0c;点赞哦。 学习内容&#xff08;背景知识&#xff0c;了解一下对以后学习有帮助&#xff09;&#xff1a; 前提&#xff1a;首先我们知道51单片机内部有21~26个特殊功能寄存器&#…

Linux: 性能分析之On-CPU和Off-CPU

文章目录1. 前言2. 概述3. 分析方法概述3.1 CPU 采样 方法3.2 跟踪 方法4. 使用火焰图分析4.1 On-CPU 分析4.2 Off-CPU 分析4.2.1 Off-CPU 两种分析方法对比4.2.2 生成 Off-CPU 火焰图5. 参考资料1. 前言 限于作者能力水平&#xff0c;本文可能存在谬误&#xff0c;因此而给读…

准备2023(2024)蓝桥杯

前缀和 一维前缀和 s[i]s[i-1]a[i]二维前缀和&#xff08;子矩阵的和&#xff09; s[i][j]s[i-1][j]s[i][j-1]-s[i-1][j-1]a[i][j] 差分 一维数组 //b是差分数组b[i]c;b[j1]-c;例题 #include<iostream> using namespace std; int n,m; int b[100002],a[100002]; vo…

【系统集成项目管理工程师】信息系统集成及服务

&#x1f4a5;信息系统集成及服务 1、信息技术基础架构库&#xff08;ITIL&#xff09; 简介&#xff1a; 最初是为了提高英国政府部门 IT 服务质量而开发&#xff0c;但它很快在英国的各个企业中得到了广泛的应用和认可。 ITIL 包含着如何管理IT 基础设施的流程描述&#xf…

【OpenCV-Python】cvui 之 trackbar

CVUI 之 trackbar cvui::trackbar() 渲染一个 trackbar&#xff0c; 可以左右拖动或点击对数字进行增加或减少的调整。 不使用离散间隔 使用离散间隔 Python import numpy as np import cv2 import cvuidef trackbar_test():WINDOW_NAME Trackbar-Test# 创建画布frame np.z…

2023-数据质量管理方法总结

一、数据质量保障原则 如何评估数据质量的好坏&#xff0c;业界有不同的标准&#xff0c;阿里主要从4个方面进行评估&#xff1a;完整性、准确性、一致性、及时性&#xff1b; 1.完整性 数据完整性是数据最基础的保障&#xff1b; 完整性&#xff1a;指数据的记录和信息是否…

Redis高级功能

目录 1.RDB 持久化 1.1生成RDB文件的命令 1.2RDB 文件结构 1.3RDB 文件结构 - database 部分 2.AOF 持久化 2.主从复制 2.1重同步 - 完整重同步 2.2重同步 - 部分重同步 2.2.1重同步 - 部分重同步的实现 - PSYNC的实现原理 3.复制的具体过程 3.Sentinel 哨兵模式 …

MySQL Workbench使用入门

软件介绍 MySQL Workbench 是可视化数据库设计软件&#xff0c;为数据库管理员和开发人员提供了一整套可视化的数据库操作环境&#xff0c;主要功能有数据库设计与模型建立、SQL 开发&#xff08;取代 MySQL Query Browser&#xff09;、数据库管理&#xff08;取代 MySQL Adm…

【Vue框架】Vue2中element-ui/mint-ui组件库——element-ui引入组件以及使用案例、mint-ui引入组件及使用案例

文章目录一、element-ui/mint-ui组件库1.1 element-ui使用步骤1.1.1 引入组件1.1.2 修改 .babelrc文件1.2 mint-ui的使用1.2.1 安装引入组件1.2.2 Mint-ui相关组件一、element-ui/mint-ui组件库 element-ui 提供了大量的组件&#xff0c;如&#xff1a;布局组件、表单组件、JS…