【Linux】进程周边005之环境变量

news2024/11/25 17:22:45

 

👀樊梓慕:个人主页

 🎥个人专栏:《C语言》《数据结构》《蓝桥杯试题》《LeetCode刷题笔记》《实训项目》《C++》《Linux》

🌝每一个不曾起舞的日子,都是对生命的辜负


目录

前言

1.环境变量是什么?

1.1查看环境变量的方法

1.2常见的环境变量

1.2.1PATH

1.2.2USER

1.2.3PWD

1.2.4HOME

2.环境变量的特性

2.1补充知识:命令行参数

2.1.1int argc与char* argv[]

2.1.2char* env[]

2.2环境变量如何具有全局属性?

3.环境变量的代码获取和设置

3.1代码获取环境变量

3.1.1通过main函数的第三个参数获取环境变量(不常用)

3.1.2通过getenv()函数获取环境变量(常用)

3.1.3通过第三方变量environ获取环境变量(不常用)

3.2设置环境变量

3.3本地变量的设置与查看

3.4unset取消环境变量或本地变量

4.环境变量的配置文件


前言

本篇文章博主将会与大家共同学习环境变量,那么环境变量究竟在扮演着什么样的角色呢?

为什么我们在编写C/C++代码时,不需要显式的告诉编译器我们所需要链接的动态静态库在哪,但链接照样可以成功并生成可执行程序,其实这里就是有环境变量的辅助。


 欢迎大家📂收藏📂以便未来做题时可以快速找到思路,巧妙的方法可以事半功倍。 

=========================================================================

GITEE相关代码:🌟fanfei_c的仓库🌟

=========================================================================


1.环境变量是什么?

环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数。

下面带你认识几种环境变量来辅助你理解环境变量。

1.1查看环境变量的方法

实例:echo $NAME    //NAME:你的环境变量名称

实例:env    //显示所有环境变量 

1.2常见的环境变量

1.2.1PATH

如何执行一个可执行程序?


可是为什么系统自带的命令(本质就是可执行程序)不需要带文件路径呢?

比如:

 其实就是环境变量PATH的配置,我们查看一些PATH的内容:

我们发现pwd的路径就在PATH中,也就是说,可执行程序的路径如果在环境变量PATH中,那么就可以不需要带文件路径的执行了。

我们来试试:

你当然可以将你的可执行程序放到环境变量中的路径下,但是我并不推荐你这样做,因为你会污染你的系统目录,从而引发一些不必要的麻烦。

所以你可以这样做:修改环境变量。

注意:如果你不慎覆盖了PATH,可以直接关闭XSHELL,因为你覆盖的PATH是加载到内存中的,重启XSHELL会重新读取磁盘中的文件,重新初始化PATH。 

1.2.2USER

当我们执行whoami时,系统是如何知道当前用户是谁的,是因为有USER这个环境变量。

1.2.3PWD

当我们执行pwd时,系统是如何知道当前路径的,是因为有PWD这个环境变量。

1.2.4HOME

当我们访问家目录时,系统是如何知道家目录在哪的,是因为有HOME这个环境变量。

好了,举这些例子都是为了解释说明环境变量的概念。

定义变量的本质其实是开辟空间,所以系统的环境变量本质就是系统或bash开辟的一块内存空间,存放着名称和数据。


2.环境变量的特性

环境变量通常具有全局属性,可是为什么呢?

其实是因为环境变量会被子进程继承下去,所以环境变量才具有全局属性。

那么我们就来探究下这个继承的过程,但在开始前我们需要一点补充知识。


2.1补充知识:命令行参数

main函数有参数么?

之前学习C/C++时,我从未见过main函数有参数。

但实际上main函数拥有三个参数:

2.1.1int argc与char* argv[]

  • 第一个参数argc:表示argv数组中存放的字符指针个数
  • 第二个参数argv:存储的是相关的字符指针,指针指向的是一个个的字符串

那我们来打印一下试试,这两个形参是什么内容:

 我们发现打印出来的好像是我们输入的命令啊。

所以我们来推测一下命令行解释器bash会干什么:

  1. printf("[ff@hecs-235417 test_23_12_09]$ ");
  2. char buffer[1024];
  3. scanf("%s",buffer);//fgets()
  4. 然后将输入进来的字符串传递给main函数的char* argv[],字符串数组的元素个数传递给int argc。

那我们再来写一段代码:

int main(int argc, char* argv[], char* env[])
{
    if (argc != 4)
    {
        printf("Usage:\n\t%s -[add|sub|mul|div] x y\n\n", argv[0]);
        return 1;
    }

    int x = atoi(argv[2]);
    int y = atoi(argv[3]);

    if (strcmp("-add", argv[1]) == 0)
    {
        printf("%d+%d=%d\n", x, y, x + y);
    }
    else if (strcmp("-sub", argv[1]) == 0)
    {
        printf("%d-%d=%d\n", x, y, x - y);
    }
    else if (strcmp("-mul", argv[1]) == 0)
    {
        printf("%d*%d=%d\n", x, y, x * y);
    }
    else
    {
        printf("unknown!\n");
    }
    return 0;
}

 也就是说这两个参数就可以让我们通过不同的选项,使同一个程序执行它内部不同的功能。

这是不是就是我们平时使用的指令后面跟上不同的选项,执行内部不同的功能!?

命令行参数也是Linux指令选项的基础。 


2.1.2char* env[]

同样的我们来打印看看该参数传递了什么?

int main(int argc, char* argv[], char* env[])
{
    printf("I am a process, pid: %d, ppid: %d\n", getpid(), getppid());
    for (int i = 0; env[i]; i++)
    {
        printf("env[%d] -> %s\n", i, env[i]);
    }
    return 0;
}

 欸,这不是环境变量么!

也就是说main函数的第三个参数传递的是环境变量!


2.2环境变量如何具有全局属性?

上面介绍main函数的第三个参数char* env[]时,我们发现他传递的是环境变量,也就是说环境变量具有全局属性的方法就是通过子进程继承父进程的环境变量,而其传递所用的方式就是该参数。

比如:bash在创建子进程时会维护两张表,一张表为命令行参数字符串数组,另一张表为环境变量字符串数组,bash作为父进程会将这两张表传递给子进程,子进程通过main函数的第三个参数进行接收。


3.环境变量的代码获取和设置

3.1代码获取环境变量

3.1.1通过main函数的第三个参数获取环境变量(不常用)

首先第一种通过代码获取环境变量的方式就是利用main函数的第三个参数,前面已经讲过了,这里就不多赘述了。

3.1.2通过getenv()函数获取环境变量(常用)

int main()
{
    const char* username = getenv("USER");
    printf("username: %s\n", username);
    return 0;
}

 那我们可以利用他来做点什么呢?

识别用户:

int main()
{
    const char* username = getenv("USER");
    if (strcmp(username, "ff") == 0 || strcmp(username, "fanzimu") == 0)
    {
        printf("this is my process core function\n");
    }
    else
    {
        printf("你没有权限\n");
    }
    return 0;
}

3.1.3通过第三方变量environ获取环境变量(不常用)

首先我们通过man指令来查看下environ

environ是指向环境变量字符串数组的二级指针。

所以我们可以通过该二级指针获取环境变量。

代码如下:

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

3.2设置环境变量

实例:export AGE=22

相当于给bash导出的环境变量,当执行myprocess后,bash是myprocess的父进程,所以myprocess继承了父进程的环境变量,所以该环境变量也就具有了全局属性。


3.3本地变量的设置与查看

注意:本地变量无法再env表中查到,且本地变量不会被子进程继承,不全局,只在bash中有效。

set命令:显示本地定义的变量和环境变量。

3.4unset取消环境变量或本地变量

实例:unset [变量名]


4.环境变量的配置文件

我们之前说环境变量是内存中的数据,我们每次在bash上修改环境变量,下次重登录的时候,所有环境变量会初始化,之前修改的内容就会被重新覆盖成最开始的内容,那很明显,这是因为环境变量是从磁盘中的某个文件中读取而来的。

环境变量的配置文件:.bash_profile

该配置文件在每个用户的家目录下。

如果我们对其内容进行修改:

下次重登录时,我们发现修改的环境变量被读取了:

讲完环境变量,你是否可以理解为什么我们每次登录默认所在的路径就是你自己的家目录呢?

那是因为每次登陆最开始系统需要读取你自己的环境变量配置文件! 


 =========================================================================

如果你对该系列文章有兴趣的话,欢迎持续关注博主动态,博主会持续输出优质内容

🍎博主很需要大家的支持,你的支持是我创作的不竭动力🍎

🌟~ 点赞收藏+关注 ~🌟

=========================================================================

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

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

相关文章

引用阿里图标库,不知道对应的图标是什么,可在本地显示图标ui,再也不要担心刚来不知道公司图标对应的是什么了

项目中使用了阿里的图标库&#xff0c;但是无法看到对应显示什么&#xff0c;每次都要去阿里图标库里面找 在下载下来的文件中会发现有两个文件一个是iconfont.css和iconfont.json&#xff0c; 这两个文件的数据可以拿到然后显示在页面上 有两个问题&#xff1a; 1&#xff1a…

【Hadoop】执行start-dfs.sh启动hadoop集群时,datenode没有启动怎么办

执行start-dfs.sh后&#xff0c;datenode没有启动&#xff0c;很大一部分原因是因为在第一次格式化dfs后又重新执行了格式化命令&#xff08;hdfs namenode -format)&#xff0c;这时主节点namenode的clusterID会重新生成&#xff0c;而从节点datanode的clusterID 保持不变。 在…

ansible远程操作主机功能和自动化运维

ansible 两个功能&#xff1a;1、远程操作主机功能 2、自动化运维&#xff08;play 剧本 yaml&#xff09; 简述&#xff1a; 是基于python开发的配置管理和应用部署工具。在自动化运维中&#xff0c;现在是异军突起。 Asible能批量配置&#xff0c;部署&#xff0c;管理上千…

智能环境与可持续发展:人工智能为地球未来添翼

导言 在全球迅速发展的背景下&#xff0c;人工智能技术的应用逐渐深入到环境保护和可持续发展领域。随着全球环境问题的加剧&#xff0c;人工智能技术在环境和可持续发展领域的应用成为推动绿色未来的关键力量。本文将深入探讨人工智能在智能环境中的角色&#xff0c;以及如何通…

保护数据库数据安全就用行云管家!全方位保障!

对于企业而言&#xff0c;数据库是企业核心信息的存储和处理中心&#xff0c;所以保障数据库安全至关重要。而如何保障数据库数据的安全性也成为了企业亟待解决的问题。行云管家数据安全运维平台作为全面的数据安全运维平台&#xff0c;通过数据运维的事前阻断、事中控制、事后…

基于Java SpringBoot和Vue的医院信息管理挂号系统

摘要 医院信息管理系统&#xff08;Hospital Information Management System&#xff0c;简称HIMS&#xff09;是一种应用于医疗机构的信息化管理系统&#xff0c;旨在提高医疗服务质量、降低运营成本、提高工作效率和满足患者需求。HIMS通过对医院内各种信息的集成、管理和共享…

mybatis中oracle的sql没走索引导致特别慢(未加jdbcType的)

如果直接跑sql是能走索引很快&#xff0c;在mybatis中不能&#xff0c;可能就是jdbcType的原因。 比如&#xff0c;我有一个属性A&#xff0c;在表里面是VARCHAR2类型&#xff0c;但是在mybatis中的sql是#{a}&#xff0c;缺少jdbcTypeJdbcType.VARCHAR&#xff0c;就会导致myba…

Excel小技能:excel如何将数字20231211转化成指定日期格式2023/12/11

给了一串数字20231211&#xff0c;想要转成指定格式的日期格式&#xff0c;发现设置单元格格式为指定日期格式不生效&#xff0c;反而变成很长很长的一串#这个&#xff0c;如图所示&#xff1a; 其实&#xff0c;正确的做法如下&#xff1a; 1&#xff09;打开数据功能界面&am…

列举python2和python3的区别,python 2和python 3的区别

大家好&#xff0c;本文将围绕python2和python3的区别有哪些?展开说明&#xff0c;列举 python2和python3的区别?是一个很多人都想弄明白的事情&#xff0c;想搞清楚python2和python3的区别大吗需要先了解以下几个事情。 python不同于其他语言,python3并不对python2向下兼容 …

Java刷题篇——单链表练习题上

206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 1. 题目描述 给你单链表的头节点 head &#xff0c;请你反转链表&#xff0c;并返回反转后的链表。 示例1 输入&#xff1a;head [1,2,3,4,5] 输出&#xff1a;[5,4,3,2,1] 示例2 输入&#xff1a;head [1,2] 输出&…

深入比较Input、Change和Blur事件:Vue与React中的行为差异解析

目录 前言 1. Input事件&#xff1a; 行为差异&#xff1a; 2. Change事件&#xff1a; 行为差异&#xff1a; 3. Blur事件&#xff1a; 行为差异&#xff1a; 4. 在Vue中的表现&#xff1a; Input事件&#xff1a; Change事件&#xff1a; Blur事件&#xff1a; 5.…

基于Vue的汽车服务商城系统设计与实现论文

摘 要 本课题是根据用户的需要以及网络的优势建立的一个基于Vue的汽车服务商城系统&#xff0c;来更好的为用户提供服务。 本基于Vue的汽车服务商城系统应用Java技术&#xff0c;MYSQL数据库存储数据&#xff0c;基于SSMVue框架开发。在网站的整个开发过程中&#xff0c;首先对…

【数据结构】树状数组总结

知识概览 树状数组有两个作用&#xff1a; 快速求前缀和 时间复杂度O(log(n))修改某一个数 时间复杂度O(log(n)) 例题展示 1. 单点修改&#xff0c;区间查询 题目链接 活动 - AcWing本活动组织刷《算法竞赛进阶指南》&#xff0c;系统学习各种编程算法。主要面向…

浅谈深度学习中的不同归一化层

引言 目前&#xff0c;深度学习已经彻底改变了自然语言处理、计算机视觉、机器人等许多子领域。深度学习当然涉及训练精心设计的深度神经网络&#xff0c;并且各种设计决策会影响这些深度网络的训练机制。其中一些设计决策包括 网络中要使用的网络层类型&#xff0c;例如卷积…

【python】深拷贝和浅拷贝

能使用.copy()的对象&#xff1a; 需要是能改变元素的对象比如 list 和 set 就可以改变对象&#xff0c;可以使用copy函数但是类似于 一个整数 a10 或者 元组 就不能使用copy函数&#xff0c;因为他们是不可改变的对象 深拷贝和浅拷贝 浅拷贝就是这能复制第一层元素&#xff0…

12V转24V10A升压同步整流芯片:高效能解决方案

12V转24V10A升压同步整流芯片&#xff1a;高效能解决方案 随着现代电子设备的日益普及&#xff0c;对电源管理的要求也越来越高。其中&#xff0c;升压同步整流芯片在提高电源转换效率方面发挥着重要作用。本文将为您介绍一款12V转24V10A升压同步整流芯片&#xff0c;其优异的…

Kafka 基础快速入门

1、生产者 1、生产者发送消息流程 配置生产者参数属性和创建生产者对象 构建消息:ProducerRecord 发送消息:Send 关闭生产者 2、消费者 1、消费者接受消息流程 配置消费者参数属性和创建消费者对象 订阅主题 拉取消息并进行消费处理 提交消费偏移量,关闭消费者 2、消费者和…

前后端传参中遇见的问题

前后端传参经常容易出错&#xff0c;本文记录开发springBootMybatis-plusvuecli项目中出现的传参问题及解决办法 1.前后端没有跨域配置&#xff0c;报错 解决方法&#xff1a;后端进行跨域配置&#xff0c;拷贝CorsConfig类 package com.example.xxxx.config;import org.spr…

基于springboot实现的销售评价系统

一、系统架构 前端&#xff1a;html | js | css | jquery 后端&#xff1a;springboot | springdata-jpa | thymeleaf 环境&#xff1a;jdk1.7 | mysql | maven 二、代码及数据库 三、功能介绍 01. 登录页 02. 业务模块-评分结果 03. 业务模块-评分管理 04. 基础模块-…

SLAM学习笔记002

严格意义上讲&#xff0c;ROS只是一套通信框架而已ros的几个特性&#xff1a; 元操作系统分布式通信机制松耦合软件框架丰富的开源功能库等 ros实际上是运行在ubuntu上的亚操作系统&#xff0c;或者说软件框架。但提供硬件抽象、函数调用、进程管理这些类似操作系统的功能ros…