【Linux】理解Linux环境变量
🍎作者:阿润菜菜
📖专栏:Linux系统编程
初识环境变量
什么是环境变量
我们平常所用的Linux指令其实也是可执行程序,和我们自己写的二进制程序没什么两样,那么为什么我们在执行自己的程序的时候需要加上 ./,而在我们执行系统提供的指令时(可执行程序),为什么不需要加上./ 呢?
其实时我们要执行一个程序或者指令,必须先找到这个程序。
所以我们在执行自己写的程序时,要加上./(当前路径),其实就是为了找到我们所写的程序,而系统指令实际上是系统默认帮我们找到其程序的位置并且执行,如果想不带./的执行自己的程序,那就需要将程序安装(安装的本质就是拷贝)到/usr/bin目录下面,也就是系统安装指令的路径当中。但我们不建议这么做,因为未知的程序可能会有污染系统指令池的风险。
所以什么是环境变量?
概念: 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
就是说,比如我们在执行C/C++代码代码时,会调用语言的库就,那在链接的时候,我们从来不知道我们所需要链接的动静态库在哪里,OS照样可以链接成功,生成可执行程序,原因就是有 相关 环境变量帮助编译器去进行查找。
添加程序路径到PATH环境变量里(像指令一样运行程序)
像是ls这样的指令程序就是在/usr/bin目录下的,那为什么在/usr/bin路径下的程序,系统就可以找到呢?其实是因为系统里面存在环境变量PATH,操作系统在启动的时候,会在shell的上下文当中定义一个PATH变量,这个变量是全局有效的,如果想要查看内容,可以利用echo $PATH命令进行查看。
查看环境变量的方法: echo $NAME //NAME:你的环境变量名称
在执行系统指令的时候,系统会默认去PATH环境变量里面的路径,查找我们输入的指令程序,如果找到,系统就会执行这个程序,如果没有找到就会报错command not found,如果我们想要想要像:ls、pwd、tree等命令一样使用起来不带路径的话,我么只需要将我们的可执行程序添加到PTAH中任一一条目录下或者将我们的路径追加到PATH环境变量下面;
另外我们可以任意修改PATH的值,因为只要重新退出登录,PATH环境变量就又会恢复了
我们可以用export指令来将shell变量导入到环境变量PATH里面,导入的时候需要先将老的环境变量导入进去然后在加上新的路径(追加路径),否则会出现你的路径直接覆盖掉之前环境变量PATH里面的所有路径的情况,PATH里面的路径下的所有程序都被默认为是系统指令。
PATH=$PATH:路径
像这样,过后我们不仅可以不带路径的使用我们追加的路径下的可执行程序,同时也不会影响ls等命令的使用。
另外我们的环境变量是内存级的,所以在你将自己的路径导入到环境变量PATH之后也只是暂时的,等你退出xshell之后,你的环境变量就又会恢复到默认的样子了
下面我们来看一些常见的环境变量:
PATH : 指定命令的搜索路径;
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
HOME环境变量记录当前用户的工作目录在具体的哪个路径
cd的本质其实就是shell在解析指令时,看到了波浪号,shell就会直接调用环境变量HOME的值
SHELL : 当前Shell,它的值通常是/bin/bash
当然这都是一些比较常见的环境变量,我们如果想要查看所有环境变量的话,我们可以使用 命令env
进一步理解环境变量
环境变量的作用
无论是我们自己写的程序还是操作系统提前给我们准备好的程序,想要运行都必须先加载到内存里面,因为CPU只能从内存中读取代码和数据,但是这里有一个潜在的问题,这些程序想要运行,都必须让操作系统先找到这些程序,找到这些程序才能把他们加载到内存里面.操作系统要找这些程序就必须去特定的路径下面去找这些程序,包括系统自带的指令程序和我们自己所写的程序,操作系统还有可能找头文件,找动态库静态库等等,但是为什么你说操作系统能找到这些东西,它就能一定找到呢?操作系统是如何找到这些东西的?
其实想要找到这些东西,操作系统需要做很多的准备工作,操作系统在启动的时候,他就已经默认从配置文件当中读取了他自己曾经把软件安装到了哪些路径下,他把安装到哪些路径下这些重要信息都记录在配置文件里面,等到OS启动的时候,把配置文件中的这些信息导入到内存里面,构建出一个内存级变量,这种变量就是环境变量,上面所讲的PATH环境变量就是操作系统在启动命令行解释器shell的时候,将PATH这样的变量导入到shell的上下文当中,当我们执行对应的指令的时候,我们就必须通过PATH环境变量里面指定的默认的搜索路径去查找对应的可执行程序,所以操作系统为了让我们找到可执行程序,其实做了很多的准备工作,帮我们定义了许许多多的环境变量,通过环境变量帮助我们做了很多本身我们看不见的工作,除PATH这个环境变量,其实还有很多很多的其他环境变量,操作系统需要完成其他很多我们忽略掉的工作,这就需要依靠这些它自己定义出来的环境变量,这些环境变量都有不同的用途,配色方案,当前路径,主机名,用户名,历史指令记录,默认的shell类型这些都要依靠OS他自己定义出来的环境变量去隐式的解决或处理我们看不到的问题和工作。
在不同的使用场景下,要求操作系统在启动shell之后,给我们做命令行解释的时候,必须预先设置好一批未来shell可能用到的变量,通过这些变量完成我们输入的命令的解释,所以 操作系统为了满足不同的应用场景,必须预先在自己的OS内设置一大批的全局变量,这些全局变量其实就是环境变量!
环境变量的组织方式
首先我们知道环境变量是存储的有内容的,那么这些环境变量里面的内容是从哪里来的?
答:环境变量的内容一般是由os从特定的配置文件中读取到的,当我们的os启动完毕过后,os就会读取相关配置文件里面的数据放到环境变量里面;在Linux下环境变量一般都在家目录下的.bashrc和.bash_profile;
这些环境变量也是数据,os也会对这些数据进行管理,os利用一个字符指针数组来维护这个环境变量表
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串;这个环境变量表的最后一个元素是NULL,以此来表示环境表的长度
如何获取环境变量
通过代码环境变量主要有3种方式:
1.通过main函数的参数获取:
我们都知道main函数是可以带参数的,而且最多可以带3个参数,比如:
int main(int argc,char*argv[],char*envp[]);
其中envp就是指向这个环境表的首元素指针,通过envp我们可以获取到环境变量:
#include<stdio.h>int main(int argc,char*argv[],char*envp[])
{int i=0;for(;envp[i];i++){printf("envp[%d]--->%s\n",i,envp[i]);}return 0;
}
测试结果:
2.我们也可以不用main的参数,C语言给我们提供了一个全局的字符指针,用来指向环境表,我们也可以通过这个全局的环境表来访问环境变量,这个全局的字符指针也就是:environ,我们只需要声明一下即可使用:
#include<stdio.h>extern char** environ;int main()
{int i=0;for(;environ[i];i++){printf("environ[%d]--->%s\n",i,environ[i]);}return 0;
}
- 通过系统调用getenv函数来获取:
上面的两种方法虽然可行,但是用起来实在是不方便,比如我向访问一下USER这个环境变量,还得我自己去写匹配算法去一个一个寻找,很是麻烦,而是用getenv函数则会省去我们自己写匹配算法查找的过程,我们只需要告诉getenv我们需要获取哪个环境变量即可,getenv就会返回对应环境变量的内容;如果没有找到对应环境变量则返回NULL
#include <stdio.h>
#include <stdlib.h>
int main()
{printf("%s\n", getenv("USER"));printf("%s\n", getenv("PATH"));return 0;
}
利用该函数我们可以搞一个只允许私人(如IKun)使用的pwd命令!
#include <stdio.h>
#include <stdlib.h>
#include<string.h>
#include<assert.h>
#define NAME "Ikun"
void Mypwd()
{char* pwd = getenv("PWD");assert(pwd);printf("%s\n", pwd);
}
int main()
{char* user = getenv("USER");assert(user);if (strcmp(NAME, user) == 0){Mypwd();}else{printf("\n小黑子...\n");}return 0;
}
为了保持我们的pwd指令能像系统的pwd指令那样执行,我们需要将我们的代码所形成的可执行程序添加到PATH其中一个默认目录下:
测试:
环境变量和本地变量的关系(本地变量包含环境变量)
显示本地变量和环境变量的指令:
- set指令可以显示shell中的环境变量和非环境变量(包括本地变量)
- env可以显示所有的环境变量
导入环境变量和取消环境变量
export MYVAL="youcanseeme"
unset MYVAL
由于自己定义的环境变量默认就是字符串,所以在定义的时候既可以带上双引号,也可以不带双引号,但如果出现定义的环境变量带空格的话,就必须带上双引号了,所以还是建议在定义的时候带上空格。
1.父进程shell定义的本地变量不会被子进程继承下去,但是父进程的环境变量是会被子进程继承下去的,继承的原因就是为了满足不同的应用场景,因为许多系统指令(ls、whoami、pwd、which、su - )都会涉及到使用环境变量,所以这些指令(子进程)必须继承父进程bash的环境变量,以满足不同的使用场景。
所以环境变量是具有全局性的,因为无论是父进程还是子进程都有环境变量,子进程的环境变量是从父进程继承得来的。
2.本地变量只会在当前进程bash内部有效,因为它不会被继承下去,具有局部性。
命令行参数
上面我们再介绍利用代码获取环境变量的时候,提到了可以利用main函数的参数来获取,其中我们介绍了envp参数,但是argc、argv参数是什么呢,现在我们就来理解一下这两个参数的意义:
从结构上我们可以看到argv与envp是同一个类型,于是我们可以大胆的猜测一下,argv也可能表示的是一张表!其中argc是这个表的长度!
打印出来看看:
#include <stdio.h>int main(int argc, char* argv[], char* envp[])
{int i = 0;for (i=0; i < argc; i++){printf("argv[%d]---> %s\n", i, argv[i]);}return 0;
}
1. main函数中的第一个参数是命令行中运行程序的时候字符串的个数,以空格为分隔符,比如上面运行时-a -b -c等,实际上是三个字符串,./mycmd也是一个字符串,所以argc代表的就是字符串的个数,argv指针数组中的指针,指向的就是这些字符串,通过程序运行结果和代码,可以证明这个结论,argv数组中打印出来的值实际上就是这些字符串,所以main函数中的第二个参数就是命令行参数表,表中的指针指向命令行中的所有字符串
2. 系统指令其实就是C语言写的程序,那么它在带指令运行的时候,也能实现不同的功能,这是怎么做到的呢?实际上在实现的代码中的main函数就是需要argc、argv这样的参数实现的
3.所以命令行参数最大的意义就是,通过不同的参数(也就是执行时携带的选项)使得进程拥有不同的功能。
类似的在windows下的命令提示符当中,我们也可以通过不同的命令行参数,来使得进程实现不同的功能,例如下面的关机指令,可以设置关机时间,也可以取消关机,选择关机,通过-t、-a、-s等参数实现。
相关文章:
【Linux】理解Linux环境变量
🍎作者:阿润菜菜 📖专栏:Linux系统编程 初识环境变量 什么是环境变量 我们平常所用的Linux指令其实也是可执行程序,和我们自己写的二进制程序没什么两样,那么为什么我们在执行自己的程序的时候需要加上 ./…...
ISCSI块存储-集群
ISCSI块存储-集群 1、ISCSI概述 ISCSI与SCSI原理对比 底层都是硬盘 ISCSI第二层就是通过gateway/网络获取–>SCSI:是直连获取 常见的用于ISCSI服务的网络拓扑类型 SAN:Storage Area Network:存储区域网络; 多采用告诉光纤…...
11.Maxwell 部署
Maxwell 部署 一、环境准备 1、确保服务器上已经安装好了zookeeper、kafka、MySQL软件; (1)启动zookeeper: /usr/app/zookeeper3.4/bin/zkServer.sh start(2)启动三台主题的kafka 启动:bin/kafka-serv…...
一文速学-GBDT模型算法原理以及实现+Python项目实战
目录 前言 一、GBDT算法概述 1.决策树 2.Boosting 3.梯度提升 使用梯度上升找到最佳参数 二、GBDT算法原理 1.计算原理 2.预测原理 三、实例算法实现 1.模型训练阶段 1)初始化弱学习器 2)对于建立M棵分类回归树: 四、Python实现 …...
前端——2.HTML基本结构标签
这篇文章我们从0来介绍一下HTML的相关标签内容 目录 1.HTML语法规范 1.1基本语法概述 1.2标签关系 2.HTML的基本结构标签 2.1第一个HTML网页 2.2基本结构标签总结 1.HTML语法规范 下面,我们来看一下HTML的语法规范的内容 1.1基本语法概述 首先,…...
OAK深度相机使用不同镜头和本地视频流进行模型推理
编辑:OAK中国 首发:oakchina.cn 喜欢的话,请多多👍⭐️✍ 内容可能会不定期更新,官网内容都是最新的,请查看首发地址链接。 ▌前言 Hello,大家好,这里是OAK中国,我是助手…...
[项目] Boost搜索引擎
目录 1.项目相关背景 2.项目宏观原理 3.技术栈和项目环境 4.正排索引&&倒排索引 5.去标签与数据清洗 6.构建索引模块Index 6.1正排索引 6.2 建立倒排 jiebacpp使用 建立分词 7.搜索引擎模块Searcher Jsoncpp -- 通过jsoncpp进行序列化和反序列化 处理Cont…...
解决新版QGIS找不到Georeferencer插件
目录1. 问题分析1.1 去 Raster 找,没找到1.2 去插件搜,未搜到1.3 插件库里也搜不到2. 解决办法在 QGIS 3.30中,按常规办法,找不到 Georeferencer插件,它并没有被安装,在库中也找不到它, 请问问题…...
c---冒泡排序模拟qsort
一、冒泡排序 二、冒泡排序优化排各种类型数据 文章目录一、冒泡排序二、冒泡排序优化排各种类型数据冒泡排序 冒泡排序原理:两两相邻元素进行比较 初级版 void bulle_sort(int* a, int sz) {int i 0;for (int i 0; i < sz-1; i){int j 0; for (j 0; j…...
Java知识复习(十四)JS
1、数据类型 基本数据类型:null、undefinde、boolean、string、number、symbol(ES6新增)引用数据类型:Function、Array、Object、Map和Set(ES6新增) 2、let、var和const的区别 var定义的变量,…...
代码随想录刷题-数组-移除元素
文章目录写在前面习题我的想法暴力解法双指针写在前面 本节对应代码随想录中:代码随想录 习题 题目链接: 27. 移除元素- 力扣(LeetCode) 给你一个数组 nums 和一个值 val,你需要原地移除所有数值等于 val 的元素&a…...
聚观早报 |拼多多跨境电商业务正式登陆澳洲;中国加快6G网络研发
今日要闻:拼多多跨境电商业务正式登陆澳洲;全球自动驾驶公司排名特斯拉垫底;中国将加快 6G 网络研发;B站再次“崩”上热搜!已闪电修复;微软将必应AI聊天每次对话上限增加至8条拼多多跨境电商业务正式登陆澳…...
MDK Keil5 创建Stm32工程-理论篇(这里以Stm32F103Zet6为例)
一、文件夹创建与文件说明整个工程可以粗略的划分为几个文件夹:BSP底层驱动比如GPIO\Timer等驱动文件CMSIS内核相关的文件Firmware生成的固件下载文件Mycode用户编写的相关文件,主要编写的文件都在这个文件夹里Project工程文件startup芯片启动文件STM32F…...
应届大学生学什么技术好?哪些技术适合年轻人?
到了毕业季,应届大学生面临的就是就业问题,很多专业的大学生难以找到对口的工作,或是不得已随便就业,或者是学个技术高薪就业,那么,问题来了,应届大学生学什么技术好?哪些技术适合年…...
车企数据分类分级的实践指南出炉!“数据安全推进计划”发布,奇点云参编
日前,“数据安全推进计划”(DSI)正式发布《智能网联汽车数据分类分级实践指南》(下文简称“指南”),旨在以合规为主要导向,明确智能网联汽车数据分类分级的方法论,为数据全生命周期的…...
Nginx学习 (2) —— 虚拟主机配置
文章目录虚拟主机原理域名解析与泛域名解析(实践)配置文件中ServerName的匹配规则技术架构多用户二级域名短网址虚拟主机原理 为什么需要虚拟主机: 当一台主机充当服务器给用户提供资源的时候,并不是一直都有很大的用户量&#…...
Java 动态代理简述和实例
Java动态代理是一种在运行时动态创建代理对象的技术。它可以让我们在不修改原始代码的情况下,对原始对象进行增强或者添加额外的行为。这种代理方式可以用于很多场景,例如AOP编程、RPC框架等。动态代理是基于Java反射机制实现的,它允许程序在…...
Unity编译器扩展(Advanced Editor Scripting)
Untiy编译器扩展允许我们对编译器的增加自己编写的的功能菜单栏MenuItemContextMenu和ContextMenuItemContextMenuContextMenuItemMenuItem 该属性允许您将菜单项添加到主菜单和检查器窗口上下文菜单。 该属性将任何静态函数转换为菜单命令。只有静态函数可以使用该属性。 Men…...
AFR机制及流程介绍
AFR(Auto Fast Return)不符合3GPP协议标准,因此终端默认是disable状态。如果运营商有要求可以配置开启。 AFR有两种场景 2G或者3G AFR到4G4G AFR到5G3G AFR TO 4G AFR到LTE功能的作用就是终端从LTE Handover或者重定向到3G进行业务,等业务做完后能够快速回到LTE网络。...
9.Hbase 部署
9.Hbase部署 注意事项: 1:必须事先安装 Hadoop分布式集群,zookeeper分布式集群 2:查看版本号: hbase version1、解压文件并改名 tar -zxvf /opt/software/hbase-2.2.3-bin.tar.gz -C /usr/app/ mv hbase-2.2.3/ hba…...
【maven 学习记录】
maven 学习记录一、maven基础1. maven是什么2. maven的作用3. maven的下载安装4. maven仓库5. maven坐标6. 第一个maven项目 手工实现7. maven插件8. 依赖管理9. 生命周期二、maven进阶一、maven基础 1. maven是什么 maven的本质是一个项目管理工具,将项目开发和管…...
NB-IOT宣传这么多年,这次总算用好了吧
一、方案概述随着实体经济快速发展,石化、港口、货场、工地等区域规模日益扩大,厂区面积广阔、环境复杂、作业人员和车辆众多,如无法实时掌握工作人员状态及外来人员位置、外来车辆情况等问题,将存在非常大的安全隐患。今天小编介…...
sort函数对结构体|pair对组|vector容器|map排序|二维数组的第x列 的排序
目录 sort对 vector容器 sort对 vector<pair<int,int>>对组 sort对 结构体 结构体外部规定排序 结构体内部运算符重载 map容器的排序 map的键排序 map的值排序 sort对二维数组的排序 sort对 vector容器 sort()函数可以用于对vector容器进行排序。具体来…...
Java定时器Timer的使用
一、Timer常用方法 Timer应用场景: 1、每隔一段时间执行指定的代码逻辑(即按周期执行任务) 2、指定时间执行指定的代码逻辑 为方便测试并查看运行效果,首先先建一个类并继承TimerTask,代码如下: package timerTest…...
MySQL安装和配置
下载官网下载mysql解压版本:配置环境变量下载完成后直接解压到需要放的文件夹,根据文件夹来配置环境变量;新建系统变量,变量名自取,值是MySQL的目录编辑path环境变量,加上MySQL的bin目录 %MYSQL_HOME%\bin配…...
openpnnp - 载入板子后,要确定板子的放置角度
文章目录openpnnp - 载入板子后,要确定板子的放置角度概述用openpnp提供的功能来确定被夹住的板子的左下角原点位置和板子的角度备注ENDopenpnnp - 载入板子后,要确定板子的放置角度 概述 设备是有夹具的, 用百分表打过, 夹具本身在Z方向的平行度是没问题的. 但是, PCB板子的…...
HCIP知识点(前三天)
复习HCIA: 一、TCP/IP模型,OSI模型 OSI 开放式系统互联参考模型 应用层 抽象语言—>编码 表示层 编码—>二进制 会话层 应用程序内部的区分地址(无标准格式) 传输层 TCP/UDP – 分段(受MTU限制)、端…...
模板学堂丨妙用Tab组件制作多屏仪表板并实现自动轮播
DataEase开源数据可视化分析平台于2022年6月正式发布模板市场(https://dataease.io/templates/)。模板市场旨在为DataEase用户提供专业、美观、拿来即用的仪表板模板,方便用户根据自身的业务需求和使用场景选择对应的仪表板模板,并…...
C++:初识函数模板和类模板
目录 一. 泛型编程 二. 函数模板 2.1 什么是函数模板 2.2 函数模板的实例化 2.2.1 函数模板的隐式实例化 2.2.1 函数模板的显示实例化 2.3 函数模板实例化的原理 2.4 模板函数调用实例化原则 三. 类模板 3.1 什么是类模板 3.2 类模板的实例化 一. 泛型编程 泛型编程…...
3.8妇女节如何做好TikTok网红营销?
3月8日是国际妇女节,这一节日已经成为全球关注女性权益和平等的标志性日子,TikTok上话题#internationalwomensday累计播放超10亿次,话题#WomensDay2023累计播放量也将近300万次。 这个特别的日子为品牌提供了一个很好的营销机会。据Nox聚星了…...
开网站做备案需要什么资料/企业培训权威机构
文章目录Rust的智能指针--RefCell<T>注意:Rust的智能指针–RefCell 现在我定义一个接口Messager,用来send消息。 pub trait Messager {fn send(&self, msg: &str); }然后一个LimitTracker类型根据指定的配额来send消息* pub struct Limi…...
个人网站的作用/济南网站建设哪家好
房地产是支柱产业占GDP的比重很高 房地产是民生产业,老百姓的财富,60%在房地产,也该稳定; 房地产是半金融产业,大量的按揭贷款,它崩盘的话,对金融机构也是问题; 房地产还和大量的供应…...
wordpress 网店 主题/打开百度网页版
打比方一个类里边有多个内部类,怎样获取该类里边指定的某一个内部类public class FactoryTest {Testpublic void test2(){FactoryTest factoryTest new FactoryTest();Class extends FactoryTest> clazz factoryTest.getClass();Class>[] classes clazz.ge…...
网页传奇版本/潍坊seo关键词排名
下一代安全企业Palo Alto Networks(纽交所代码:PANW)近日详细披露了一款最新“BackStab”恶意软件,该攻击模式主要是从存储在被感染电脑上的移动设备备份文件中窃取私人信息。Palo Alto Networks公司Unit 42威胁情报团队在白皮书中…...
网站建设柒首先金手指2/竞价排名适合百度吗
第一次做性能测试,按照操作文档磕磕碰碰的完成了,并且拿到了结果,看到一堆的指标和数据,还是傻眼了,不知道各个指标是什么意思了。 咨询了大牛和度娘,消化理解了一下,不知道是不是正确的。 CPU使…...
长春火车站疫情防控咨询电话/西安seo排名
使用跨平台安装打包工具InstallAnywhere的用户应该熟悉InstallAnywhere的脚本中如何添加变量,$VARIABLESNAME$。运行时安装包会将两个“$”符号之间内容替换成实际变量值,如果没有对应变量,则换为空。所以有关“$”字符使用注意事项ÿ…...