Linux 环境变量 二

news2024/11/19 15:28:39

目录

获取环境变量的后两种方法

环境变量具有全局属性

内建命令

和环境变量相关的命令

c语言访问地址

重新理解地址

地址空间


获取环境变量的后两种方法

main函数的第三个参数 :char* env[ ]

也是一个指针数组,我们可以把它的内容打印出来看看。

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

return 0;
}

我们再把pid也打印出来看看:

输入命令:

!man getpid

我们把这两个头文件加上

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

return 0;
}

 就可以把我们的此程序的环境变量打印出来:

这个获取环境变量的方法和我们输入"env"命令获取的环境变量是一样的:

我们之前说过如果我们把PATH置空,很多系统命令都用不了了:

但是我们重启xshell之后就又可以用了。这是因为我们置空的是加载进内存的PATH。

我们重启之后系统解释器会重新读取环境变量表,形成新的环境变量,环境变量是脚本配置文件的形式存在的的。

在家目录下有个隐藏文件,bash_profile.

环境变量表就在这个文件里面。

假设我们自己写一个环境变量,

然后用env调用环境变量,通过管道只打印我们自己写的环境变量,显示找不到:

这是因为我们写的环境变量并没有被加载进环境变量表。

我们可以通过 "export"命令把我们写的环境变量加载进环境变量表里面,再通过env打印就可以打印出来了。

但是我们重启xshell之后我们配置的这个环境变量仍然会消失不见。只有当我们去家目录下面的bash_profile文件下写入我们的环境变量才能再次重启之后仍然会存在。

vim ~/.bash_profile

此刻我们就可以把我们自定义的变量打印出来看看:

假如我们不想给main函数传参呢?

有个外部变量叫   environ

 它指向了char * env[ ]

 我们把environ打印出来,main函数不带参照样可以把环境变量打印出来。

 
int main()    
{    
    extern char** environ;    
    int i=0;                                                                                                     
    for(;environ[i];i++)    
    {    
        printf("%d,%s",i,environ[i]);    
    }    


return 0;
}

到目前为止,我们获取环境变量的方法有:

main函数传参         getenv[  ]                 char** environ[  ] 

环境变量具有全局属性

我们在我们将才的进程里再写个子进程,看它能获取我们子进程的环境变量吗

#include<stdio.h>                                                  
                                                                   
#include<stdlib.h>                                                 
#include<string.h>                                                 
#include<sys/types.h>                                              
#include<unistd.h>                                                 
                                                                   
int main()                                                         
{                                                                  
    pid_t id=fork();                                               
    if(id==0)                                                      
    {                                                              
    extern char** environ;                                         
                                                                   
    int i=0;                                                       
    for(;environ[i];i++)                                           
    {                                                              
        printf("%d,%s",i,environ[i]);                              
    }                                                              
                                                                   
    }                                                              
                                                                   
    sleep(3);         

return 0;
}

 照样可以,这也证明了环境变量具有全局属性。

我们自定一个本地变量

OUR_ENV=333

 然后我们再把这个本地变量打印出来

 #include<stdio.h>    
      
  #include<stdlib.h>    
  #include<string.h>    
  #include<sys/types.h>    
  #include<unistd.h>    
      
  int main()    
      
  {                                                                                                              
printf("OUR_ENV_ENV:%S\n",getenv("OUR_ENV"));


return 0;
}

 注意:因为是子进程,所以我们没export的时候子进程获取不到我们自定义的本地变量,会显示为null

当我们export把我们定义的环境变量载入bash之后,让它成为环境变量,环境变量具有全局性,子进程就可以获取到了:

内建命令

我们再写几个本地变量:

我们发现,a,b都为本地变量,echo是一个子进程,但是可以直接打印本地变量 a,b,这是为什么?

再比如,我们把PATH置空,这时候ls,touch这种命令都用不了了,但是echo还可以用

这是因为echo是shell的内置函数,这种命令叫做linux的内建命令。

内建命令不创建子进程。

和环境变量相关的命令

 set:

把本地变量和环境变量全部打印出来:

set | grep+本地变量名

功能:打印本地变量

c语言访问地址

程序的地址空间遵守的就是下面这张图:

我们把这各个区的存的值的地址打印出来看看:

  int usa;    
  int  bbb=100;    
  int main ()    
      
  {    
      
  printf("公共代码区:%p\n",main);    
      
  const char* str="helo djwd";    
  //常量区    
  printf("常量区:%p\n",str);    
      
      
  printf("初始化全局数据区:%p\n",&bbb);    
      
W>printf("未初始化全局数据区:%p\n",usa);    
      
  char* heap=(char*)malloc(100);                                                                                 
  printf("堆区:%p\n",heap);    
      
  printf("栈区:%p\n",&str);   

 观察打印出来的地址可以发现一个问题,从公共代码区到常量区,再往下走,地址都是呈递增状态。

当到了堆区之后,从堆区到栈区,中间宽度变的特别大。

按照这个结果我们可以有这种推论:

得出结论:堆和栈相对而生。

验证

把堆区地址打印看一下:


char* heap1=(char*)malloc(100);    
char* heap2=(char*)malloc(100);    
char* heap3=(char*)malloc(100);    
char* heap4=(char*)malloc(100);    
 
    
                                                                                      
printf("堆区:%p\n",heap);    
printf("堆区:%p\n",heap1);    
printf("堆区:%p\n",heap2);    
printf("堆区:%p\n",heap3);    
printf("堆区:%p\n",heap4);    
    

可以发现堆区越来越大,这也证明堆区向上增长

把栈区地址打印一下看一下:

char* str="hello";
char* heap1=(char*)malloc(100);    
char* heap2=(char*)malloc(100);    
char* heap3=(char*)malloc(100);    
char* heap4=(char*)malloc(100);    
 
    
    
printf("栈区:%p\n",&str);                                                                                        
printf("栈区:%p\n",&heap);    
printf("栈区:%p\n",&heap1);    
printf("栈区:%p\n",&heap2);    
printf("栈区:%p\n",&heap3);    
printf("栈区:%p\n",&heap4);    
    

观察图我们发现栈区越往下越小

如果定义一个结构体object ,里面有三个成员变量 int a,b,c,abc谁最大?

struct d    
{    
    int a;    
    int b;    
    int c;    
}object;    
    
printf("%p\n",&object.a);                                                                                        
printf("%p\n",&object.b);    
printf("%p\n",&object.c);    
    

很明显,c最大

这是因为虽然栈区向下增长,但整体是向上增长的:

假设我们定义一个 int b,一个int类型有4个字节,那就应该有4个地址,但是我们打印b的地址,显示出来只有一个,这个地址就是最小的地址。

然后向上按照int类型访问4个字节,访问到最大字节:

类型的本质叫做偏移量

c语言中就是以起始位置+偏移量访问任何地址。

定义一个int a,打印a的地址。

a因为是常量,所以在栈区,又因为后开辟,所有地址偏小。

 现在我们a重定义为 static int a,此刻再重新打印a。我们发现a的地址变量,它和全局变量的地址是一个样子,也就是此时a就是一个全局变量:

所以我们可以说已初始化全局变量区就是静态区:

在栈区之上还有一个环境变量区和命令参数区:

重新理解地址

地址空间

写一个子进程,写一个父进程

pid_t id=fork();

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

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

相关文章

线上机器cpu负载200%告警排查

CPU告警排查思路&#xff0c;正常情况就是如下两种情况 执行任务的java线程本身存在bug&#xff0c;死循环或者操作本身耗cpu&#xff0c;导致cpu占用过高jvm发生频繁gc&#xff0c;导致cpu过高 查看耗时较高的进程 top命令&#xff0c;并按大写P以cpu利用率排序&#xff0c;确…

学习笔记3——JVM基础知识

学习笔记系列开头惯例发布一些寻亲消息 链接&#xff1a;https://baobeihuijia.com/bbhj/contents/3/196593.html JVM&#xff08;Write Once&#xff0c;Run Anywhere&#xff09; 以下是一些学习时有用到的资料&#xff0c;只学习了JVM的基础知识&#xff0c;对JVM整体进…

Nginx 部署多个安全域名,多个服务【工作记录】

以下是本人通过Docker 部署的Nginx挂载出来的文件目录 先看下 nginx.conf 配置文件内容&#xff1a;如下 ps&#xff1a;当前文件就是安装后的初始内容&#xff0c;无修改。主要关注最后一行 include /etc/nginx/conf.d/*.conf;表示引入其他目录下的.conf配置文件&#xff1b;…

构建 hive 时间维表

众所周知 hive 的时间处理异常繁琐且在一些涉及日期的统计场景中会写较长的 sql&#xff0c;例如&#xff1a;周累计、周环比等&#xff1b;本文将使用维表的形式降低时间处理的复杂度&#xff0c;提前计算好标准时间字符串未来可能需要转换的形式。 一、表设计 结合业务场景常…

MySQL(5):排序与分页

排序数据 排序规则 使用 ORDER BY 子句排序 ASC&#xff08;ascend&#xff09;&#xff1a;升序 DESC&#xff08;descend&#xff09;&#xff1a;降序 ORDER BY 子句在SELECT语句的结尾 单列排序 SELECT last_name,job_id,department_id,hire_date FROM employees ORDER…

设计师看后惊叹:当泥色走进室内空间的时候竟有此番效果

在美国的洛杉矶&#xff0c;一座引人注目的度假别墅彰显了自己的独特魅力。建筑师 Ron Radziner 说&#xff1a;“这是一座现代住宅&#xff0c;采用风化木、深色灰泥和绿色屋顶等与峡谷环境相关的材料&#xff0c;设计得通透、开放。” Zwickl 解释说&#xff1a;"他们想…

CCF CSP认证 历年真题自练Day42

题目 试题编号&#xff1a; 201512-3 试题名称&#xff1a; 画图 时间限制&#xff1a; 1.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述   用 ASCII 字符来画图是一件有趣的事情&#xff0c;并形成了一门被称为 ASCII Art 的艺术。例如&#xff0c;下图…

正点原子嵌入式linux驱动开发——Linux CAN驱动

CAN是目前应用非常广泛的现场总线之一&#xff0c;主要应用于汽车电子和工业领域&#xff0c;尤其是汽车领域&#xff0c;汽车上大量的传感器与模块都是通过CAN总线连接起来的。CAN总线目前是自动化领域发展的热点技术之一&#xff0c;由于其高可靠性&#xff0c;CAN总线目前广…

axios中get/post请求方式

1. 前言 最近突然发现post请求可以使用params方式传值&#xff0c;然后想总结一下其中的用法。 2.1 分类 get请求中没有data传值方式 经过查阅资料&#xff0c;get请求是可以通过body传输数据的&#xff0c;但是许多工具类并不支持此功能。 在postman中&#xff0c;选择get请求…

WebService接口方式和Restful接口这两者有什么区别和相同点

WebService和RESTful接口都是用于在网络上进行通信和数据交换的技术&#xff0c;但它们在设计和使用上有一些重要的区别和相似之处。 相同点&#xff1a; 基于HTTP协议&#xff1a;无论是WebService还是RESTful接口&#xff0c;它们都是通过HTTP协议进行通信的。 支持多种数据…

高防服务器与CDN防御怎么区分?

​  高防服务器和CDN防御是两种不同的网络安全防护方式。 定义上&#xff1a;高防服务器是指在传统服务器的基础上&#xff0c;增加了一系列的防御措施&#xff0c;如DDoS防护、WAF防护、IP黑白名单等&#xff0c;以提高服务器的抗攻击能力。高防服务器通常具有较强的计算和存…

知识图谱实战应用30-知识图谱在反欺诈情报分析项目中的应用实践

大家好,我是微学AI,今天给大家介绍一下知识图谱实战应用30-知识图谱在反欺诈情报分析项目中的应用实践,现代商业环境中,各类欺诈行为日益猖獗,严重影响企业的运营和社会秩序。传统的欺诈检测方法难以满足实时性和有效性方面的要求。本文介绍了采用知识图谱技术构建反欺诈情报…

纳米银簇 银纳米团簇

纳米银簇 名称&#xff1a;纳米银簇 西&#xff09;用途&#xff1a;科研 安&#xff09;描述&#xff1a;银纳米团簇是由数十个银原子组成的超小尺寸簇集体。银纳米团簇具有很高的表面积和独特的光学、电学、催化等性质&#xff0c;因此在生物学、光电子学、催化化学等领域具…

idea自动编译以及修改代码后需要执行 mvn clean install 才生效

idea自动编译以及修改代码后需要执行 mvn clean install 才生效 一. idea热部署一、开启IDEA的自动编译&#xff08;静态&#xff09;二、开启IDEA的自动编译&#xff08;动态&#xff09;三、开启IDEA的热部署策略&#xff08;非常重要&#xff09; 二. IDEA 中项目代码修改后…

笔记软件推荐!亲测好用的8款笔记软件!

​在以往的生活中&#xff0c;我们都需要用纸和笔做笔记&#xff0c;但随着时代的发展&#xff0c;许多人已经不再选择用这种传统方式&#xff0c;来记录自己重要的笔记了&#xff0c;他们都选择将重要的笔记用软件记录下来&#xff0c;将笔记保存在电脑里&#xff0c;更不容易…

一篇文章让你弄懂Java中的方法

目录 1. 方法概念及使用 1.1 什么是方法(method) 1.2 方法定义 1.3 方法调用的执行过程 1.4 实参和形参的关系 1.5 没有返回值的方法 2. 方法重载 2.1 为什么需要方法重载 2.2 方法重载概念 2.3 方法签名 1. 方法概念及使用 1.1 什么是方法(method) 方法就是一…

Web3公链之Cosmos生态的项目Celestia

文章目录 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia什么是CelestiaCelestia网络架构数据可用性问题有哪些可用的解决方案&#xff1f; 发展历史运行节点参考 Web3公链之Cosmos生态的项目&#xff1a;模块化区块链Celestia 什么是Celestia 官网&#xff1a…

SpringMVC Day 08 : 文件上传下载

前言 文件上传和下载是 Web 开发中的重要环节&#xff0c;但它们往往不那么容易实现。幸运的是&#xff0c;Spring MVC 提供了一套简单而又强大的解决方案&#xff0c;让我们可以专注于业务逻辑&#xff0c;而不必过多关注底层的文件处理细节。 在本篇博客中&#xff0c;我们…

32、github的使用小技巧

如何在github中阅读项目代码 如果要完整阅读项目代码&#xff0c; 可能要在文件间来回跳转&#xff0c;就非常麻烦。所以我们往往会把项目代码下载到本地&#xff0c;用更强大的编辑器来阅读。 在github中&#xff0c;可以这样操作&#xff1a; 登录 GitHub 后&#xff0c;直…

Android手机实时投屏利器scrcpy图文详解教程

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl scrcpy简介 scrcpy是免费开源的投屏软件&#xff0c;它支持将安卓手机屏幕投放在 Windows、macOS、GNU/Linux 上&#xff0c;并可直接借助鼠标在投屏窗口中进行交互和录制。…