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

Linux环境变量【终】

🌎环境变量


文章目录:

环境变量

    环境变量的组织方式

      创建自己的环境变量
      main函数参数
      C语言提供的变量与接口

    环境变量与本地变量

      了解本地变量
      取消本地变量和环境变量

    环境变量的出处

    总结


前言:

  上次我们简单了解了一下环境变量这个概念,今天我们继续深入了解。话不多说,开启我们今天的话题!

在这里插入图片描述


🚀环境变量的组织方式

✈️创建自己的环境变量

  我们有时候也需要配置自己的环境变量,我们可以使用如下命令:

export 变量名=内容

在这里插入图片描述
在这里插入图片描述
  这样就能创建自己的环境变量了。


✈️main函数参数

  在main函数中其实还存在一个参数:char *env[],和 argv类似,也是一个指针数组,不同的是 env的每一个指针指向的是每一行的环境变量

  我们不妨做实验将其打印出来观察:

#include<stdio.h>
#include<stdlib.h>int main(int argc, char *argv[], char *env[])
{for(int i = 0 ; env[i] ; ++i){printf("————————————————env[%d] -> %s\n", i, env[i);//为了能看出来我们是在打印}return 0;
}

在这里插入图片描述

  我们可以看到,打印出来的正是我们系统中所有的环境变量。

在这里插入图片描述

  每个程序都会收到一张环境表,环境表 是一个字符指针数组,每个指针指向环境变量字符串,也就是main函数的 env 参数。


✈️C语言提供的变量与接口

  C语言中除了main函数参数有 环境表 以外,C语言还为我们提供了第三方变量:

在这里插入图片描述
  很明显,这是一个二级指针,而它的最终指向也就是环境变量表。那么我们来证明一下:

  1 #include<stdio.h>2 #include<unistd.h>3 4 int main()5 {6     extern char **environ;7     for(int i = 0; environ[i] ; ++i)8     {9         printf("environ[%d]:%s\n", i, environ[i]);                                                                                                         10     }11     return 0;12 }


  那么程序是如何拿到环境变量表的呢?我们都知道,程序的默认父进程都是bash,那么程序就是bash的子进程,而子进程的 环境变量表其实就是从父进程bash那里继承的

  除了环境变量以外,我们也可以用 getenv 接口获取环境变量:

在这里插入图片描述
  这里需要注意的是,getenv里的内容是环境变量的名称,通过这个名称返回对应的字符串,比如下面这段代码:

#include<stdio.h>
#include<stdlib.h>
#include<unistd.h>
#include<string.h>int main()
{const char* username = getenv("USER");if(strcmp(username, "xzy") == 0){printf("this is my process core function!\n");}else {printf("your privilege low!\n");}return 0;
}

在这里插入图片描述


🚀环境变量与本地变量

✈️了解本地变量

  使用env命令只能查看环境变量,但是使用下面的命令可以查看所有的变量:

set #查看本地变量和环境变量

在这里插入图片描述
  也就是说,set不仅仅可以查看所有的环境变量,而且还可以查看本地变量。我们来看一个有趣的现象:

在这里插入图片描述
  export 我们刚刚学过,是导出自定义环境变量的命令,可以下面这个 HEHE 为什么不使用export也能定义出来?它也是环境变变量吗?而且还能被echo识别?我们不妨先看下面一段代码:

 1: myenv.c ? ?                                                                                                             ?? buffers 1 #include<stdio.h>2 #include<stdlib.h>3 #include<unistd.h>4 5 int main()6 {7     const char* myenv = getenv("HAHA");8     if(myenv == NULL) printf("get environ null!\n ");9     else printf("myenv:%s\n", myenv);                                                                                               10     return 0;                                                                                                                  11 }   

在这里插入图片描述
  我们把HAHA 换为 HEHE再看看结果:

在这里插入图片描述
在这里插入图片描述
  我们可以看到,这个时候getenv检测不出来这个 “环境变量”。

  其实,这个变量叫做 本地变量,至于为什么本地变量不能被getenv获取,这是因为 本地变量不是环境变量,本地变量只在bash有效,子进程不会继承本地变量

区别:

环境变量本地变量
作用范围环境变量是在操作系统级别定义的变量,可以被所有的子进程继承并使用,对整个系统和所有用户都有效本地变量只在定义它的当前 shell 进程中有效,对于其它的子进程不可见
存储位置环境变量通常存储在系统级别的配置文件中本地变量则只存在于当前 shell 进程的运行环境中
继承性环境变量可以被子进程继承并使用,对系统中所有的进程都是全局可见的本地变量不能被子进程继承。如果需要将本地变量转换成环境变量,可以使用export命令

✈️取消本地变量和环境变量

  如果我们自定义的环境变量或者本地变量现在不想要了,我们可以使用这条指令:

unset 环境/本地变量名#取消环境/本地变量

  比如删除我们刚刚的 HEHE 和 HAHA:

在这里插入图片描述
  这样就将 环境/本地变量删除了。


🚀环境变量的出处

  不知道大家有没有想过,我们环境变量是存在哪的呢?为什么我们开机就有这些环境变量或者本地变量呢?

  上次我们也说了,为什么我们导入的环境变量重启会消失,是因为 我们操作是内存级的,并没有保存到磁盘,而每次重启内存数据丢弃,从磁盘重新拷贝数据到内存。

  那么究竟是哪个文件?我来带大家看一看:

在这里插入图片描述
  在Linux操作系统的家目录当中,隐藏文件有这样一个文件:.bash_profile文件,我们打开这个文件:

在这里插入图片描述

  其实这就是一个脚本文件,用来导入环境变量,系统启动时,bash会读取这个脚本文件,从而获取环境变量

  而今天我们想要一个重新登陆也能使用的自定义环境变量,那么我们就可以在下方把环境变量写入并保存即可:

在这里插入图片描述
  我们保存后到终端页面,使用下面命令让文件生效,那么这个环境变量就生效了:

source .bash_profile#使bash_profile内的环境变量生效

  当然我这台机器的Linux系统bash_profile文件并未生效,可能是登录时bash并未读取.bash_profile文件,所以不能生效,但是大部分人应该是没问题的。


📒✏️总结

  •  我们了解了main函数第三个参数可以获取环境变量,以及一个变量和一个接口可获取环境变量表。
  •  我们了解了什么是环境变量什么是本地变量。
  •  我们学习了如何永久导入环境变量以及如何删除环境变量或本地变量。

在这里插入图片描述
  创作不易,如果这篇文章对您有帮助的话,还望留下一个小小的赞支持博主呀~~

相关文章:

  • element-ui checkbox 组件源码分享
  • 10、chrome拓展程序的实现
  • 01分布式搜索引擎ES
  • GT20L16S1Y标准汉字字库芯片完全解析(2)
  • 基于FPGA的UDP协议栈设计第三章_ARP层设计
  • RESTful架构
  • 零基础-MySQL数据库的基本操作
  • PWM脉宽调制技术
  • 第十节:Vben Admin实战-系统管理之角色管理实现(分页查询,修改)-中
  • creator-webview与Android交互
  • Unity:2D
  • 读算法的陷阱:超级平台、算法垄断与场景欺骗笔记19_前方的路
  • leetcode最大连续1的个数(简单)
  • docker 容器与本地主机间文件/文件夹的传输
  • 如何用VSCode和Clangd与Clang-Format插件高效阅读Linux内核源码及写驱动
  • 【个人向】《HTTP图解》阅后小结
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Angularjs之国际化
  • css属性的继承、初识值、计算值、当前值、应用值
  • Docker容器管理
  • ES10 特性的完整指南
  • gulp 教程
  • Python学习笔记 字符串拼接
  • Python中eval与exec的使用及区别
  • tweak 支持第三方库
  • vue+element后台管理系统,从后端获取路由表,并正常渲染
  • 从PHP迁移至Golang - 基础篇
  • 第十八天-企业应用架构模式-基本模式
  • 基于阿里云移动推送的移动应用推送模式最佳实践
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 前端js -- this指向总结。
  • 深度学习中的信息论知识详解
  • 事件委托的小应用
  • 通过几道题目学习二叉搜索树
  • 我的业余项目总结
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • 一文看透浏览器架构
  • ​低代码平台的核心价值与优势
  • ​马来语翻译中文去哪比较好?
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (1/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (六)激光线扫描-三维重建
  • (深入.Net平台的软件系统分层开发).第一章.上机练习.20170424
  • (转)http-server应用
  • (转)负载均衡,回话保持,cookie
  • .net framwork4.6操作MySQL报错Character set ‘utf8mb3‘ is not supported 解决方法
  • .NET HttpWebRequest、WebClient、HttpClient
  • @KafkaListener注解详解(一)| 常用参数详解
  • @ResponseBody
  • [ IOS ] iOS-控制器View的创建和生命周期
  • [20170705]lsnrctl status LISTENER_SCAN1
  • [2021ICPC济南 L] Strange Series (Bell 数 多项式exp)
  • [Android] 240204批量生成联系人,短信,通话记录的APK