【Linux】进程6——环境变量

1.什么是环境变量

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

  • 比如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
  • 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性

windows里也有环境变量

 2.认识几个环境变量

2.1.PATH

  1. PATH : 指定命令的搜索路径

        为什么我们使用指令时不用加./,而我们使用自己编译的可执行程序就需要加./?

        这个是因为使用指令的时候,系统默认在/usr/bin/里去查找,那我们自己的可执行程序为什么没有这个待遇?
        原因在于linux会给指令搜索提供一个环境变量PATH

我们可以把它显示出来

查看环境变量指令:
echo $NAME //NAME:你的环境变量名称 

        上图是我Linux用户下的PATH变量,这些路径都由:进行分隔。

        当我们输入我平时的ls、pwd等等指令时直接就可以使用,就是因为他们都是在/user/bin目录下,操作系统可以自动寻找。

        但是我们运行一个陌生路径下的可执行程序时就得声明为当前路径下,这就是因为我们在PATH环境变量中没有定义此路径。操作系统不能自动寻找。

        我们可以将一个程序放到PATH有的路径下,或者将当前的绝对路径加入到PATH变量中去,我们就可以直接使用此指令。

        

        我们可以往PATH添加路径

        这样子这个目录下

面的所有可执行程序都能当成指令来运行了

实际上,我们刚刚修改的PATH环境变量是一种在内存中的环境变量,所以无需担心。

如果不小心改错了,只需关闭Xshell并重新登录即可。这个PATH环境变量是在shell中保存的。

然而,当shell尚未存在时,即在系统启动时,环境变量是从哪里来的呢?

        实际上,这些环境变量预先存储在我们系统的一些配置文件中。当系统启动时,它们会被加载到内存中。因此,现在你不必担心你的环境变量被错误修改,只需重新启动一下,我们的环境就会恢复

2.2.HOME

  1. HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)

        在我们平是登录xshell的时候普通用户就会直接进入自己的家目录/home/xxx而root用户会进入自己家目录/root ,那么系统是怎么知道我们的工作目录的呢?
       主要原因就是因为当我们在登录时,shell就会直接识别到当前登陆账户是谁,然后给当前用户填充$HOME环境变量,当我们登录时,此时默认就直接cd到了$HOME目录下。这就是我们每次登录之后都会处于自己对应的家目录的原因。

2.3.获取环境变量env&&getenv

bash中我们可以使用env命令来获取bash从系统中继承下来的所有环境变量

我们可以通过下面这个来查询其他环境变量

也可以使用getenv来获取某一个环境变量。 

#include <iostream>
#include <unistd.h>
using namespace std;
int main()
{cout<<"PATH="<<getenv("PATH")<<endl;return 0;  
}

2.4环境变量USER

  USER环境变量用来标识当前登录的用户。在终端中输入命令echo $USER,可以查看当前登录用户的用户名。这个环境变量是bash/shell在启动时自动加载的,它记录了当前登录的用户。
        我们再来写一段demo代码:

#include <iostream>
#include <unistd.h>
using namespace std;int main()
{cout<<"USER="<<getenv("USER")<<endl;return 0;  
}

了解了上面内容,我们就可以模拟一下系统权限对普通用户和root用户的判定方式:

#include <iostream>
#include <unistd.h>
#include <cstring>
using namespace std;int main()
{char who[32];strcpy(who,getenv("USER"));if(strcmp(who,"root")==0)cout<<"root用户不受条件约束"<<endl;else cout<<"普通用户受权限约束"<<endl;cout<<"USER:"<<getenv("USER")<<endl;return 0;  
}

 

 因为有环境变量的存在,我们的系统就已经具备了能够认识你这个人是谁的能力,只要能认识你是谁,就可以和文件属性当中文件的拥有者所属组和文件所对的权限所对比,进而判定出你有没读写权限

3.命令行参数

我们C/C++中的main函数其实是可以传参的,这两个参数我们称之为命令行参数:

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

其中argv是一个指针数组,里面保存了字符串的地址,argc决定了argv中的元素个数,我们来尝试打印一下argv中的内容:

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

我们在命令行输入几个数后,打印出来就有几个。

3.1.命令行参数的作用

那命令行参数有什么用呢?看代码:

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>
#include<string.h>
int main(int argc, char* argv[])
{if (argc != 4){printf("Usage: \n\t%s -[add|sub|mul|div] x y \n\n", argv[0]);}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("%d / %d = %d\n", x, y, x / y);}return 0;}

命令行参数可以通过输入不同的选项,来控制程序执行不同的功能代码。
命令行参数为指令,工具,软件等提供命令行选项的支持! 

命令行参数是Linux指令的基础,从上面的程序我们可以联想出我们在Linux中使用的指令后面跟的就是命令行参数:

我们使用的ls -al 、ll -al等等都是命令行参数。

我们使用的环境变量不是一两个而是一堆,并且彼此之间没有关系,一般是系统内置的具有特殊用途的变量。而定义变量的本质就是开辟空间,操作系统就是在运行中开辟空间的。

3.2.main函数的第三个参数

main函数除了上面那两个参数,还有一个叫做char *env[]的参数;

int main(int argc,char *argv[],char *env[])
{return 0;
}

 我们也可以来打印一下env中的内容:

#include <iostream>
#include <unistd.h>
#include <cstring>
using namespace std;
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;
}

还可以通过第三方变量environ获取

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

argv和env的结构一模一样,所以我们的C/C++代码一共会有两张核心向量表,一张叫做命令行参数表,一张叫做环境变量表。环境变量表会从父进程中继承下来。

我们所运行的进程,都是bash的子进程, bash本身在启动的时候,会从操作系统的配置文件中读取环境变量信息,子进程会继承父进程交给我的环境变量!

3.3.验证环境变量的继承

我们可以自己定义一个环境变量导入系统中的环境变量表当中,我们想要增加一个环境变量可以使用下面命令:

export MY_VALUE=666666666666

 

可以看到我们自己定义的环境变量已经被导入到环境变量表当中。
我们接下来再去执行我们刚刚的代码:

看到env[17]了嘛!!!可以发现它里面也有 MY_VALUE 这个环境变量,说明子进程test继承了父进程 bash 的环境变量。

删除一个环境变量可以使用unset 环境变量命令。

unset MY_VALUE

4..环境变量通常是具有全局属性的

环境变量通常具有全局属性,可以被子进程继承下去

#include <stdio.h>
#include <stdlib.h>
int main()
{
char * env = getenv("MYENV");
if(env){
printf("%s\n", env);
}
return 0;
}

 直接查看,发现没有结果,说明该环境变量根本不存在

导出环境变量
export MYENV="hello world"
再次运行程序,发现结果有了!说明:环境变量是可以被子进程继承下去的!

5.常规命令&&内建命令

我们再来看这个图中,我们定义了本地变量MY_VALUE,我们的可执行程序(bash的子进程)都读不到这个变量,为什么echo可以读取到呢

我们使用可执行程序myproc去读取我们的本地变量

 其实我们命令行上执行的指令不一定都要创建子进程,就好比王婆说媒一样,一些有任务特别难的或者风险的,王婆就会找别人去帮忙说媒。如果是一些很有把握的事情,那王婆还是愿意自己去做的。

由此可以推出我们指令是有区别的:

  • 常规命令:通过创建子进程完成的
  • 内建命令:bash不创建子进程,而是有自己亲自执行,类似于bash调用了自己写,或者系统提供的函数。

所以echo是一个内建命令,它是由bash自己执行的,与此同时我们的cd命令也是一个内建命令,我们可以通过调用chdir来改变当前工作目录。

#include <iostream>
#include <unistd.h>
#include <cstring>
using namespace std;
int main(int argc,char *argv[])
{sleep(30);printf("change begin\n");if(argc==2){chdir(argv[1]);}printf("change end\n");sleep(30);return 0;
}

在命令行中输入 cd 命令的时候,bash 并不会创建子进程,而是去判断命令行参数是否为 cd,如果是就直接去调用 chdir 系统接口来切换bash的工作目录 

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

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

相关文章

[知识点] 内存顺序属性的用途和行为

C标准库中定义了以下几种内存顺序属性&#xff1a; std::memory_order_relaxedstd::memory_order_consumestd::memory_order_acquirestd::memory_order_releasestd::memory_order_acq_relstd::memory_order_seq_cst 1. std::memory_order_relaxed 定义&#xff1a;不提供同步…

通过 Python+Nacos实现微服务,细解微服务架构

shigen坚持更新文章的博客写手&#xff0c;擅长Java、python、vue、shell等编程语言和各种应用程序、脚本的开发。记录成长&#xff0c;分享认知&#xff0c;留住感动。 个人IP&#xff1a;shigen 背景 一直以来的想法比较多&#xff0c;然后就用Python编写各种代码脚本。很多…

C++青少年简明教程:文件

C青少年简明教程&#xff1a;文件 文件是指存储在计算机文件系统中的数据集合。文件可以包含各种类型的信息&#xff0c;例如文本、图像、音频视频等。在 C中&#xff0c;文件是一种数据流&#xff0c;可以用于读取或写入数据。C提供了一系列的文件操作函数&#xff0c;用于实现…

这个国际档案日,大比武放榜、直播预约、课件下载,一样都不能少!

关注我们 - 数字罗塞塔计划 - 2024年6月9日第十七个国际档案日来临&#xff0c;数字罗塞塔计划放大招&#xff1a;第二届大比武活动榜单揭晓、ARCHE-2024上海智慧档案高峰论坛直播预约、2024上半年度课件大礼包下载。如此大礼&#xff0c;岂能错过&#xff1f; PART.01 榜单…

【LeetCode 第 401 场周赛】K秒后第 N 个元素的值

文章目录 1. K秒后第 N 个元素的值&#x1f197; 1. K秒后第 N 个元素的值&#x1f197; 题目链接&#x1f517; &#x1f427;解题思路&#xff1a; 前缀和 小规律&#x1f34e; &#x1f34e; 从上图观察可知&#xff0c;规律一目了然&#xff0c;arr[i] arr[i] 对上一…

2024-6-9

今日安排&#xff1a; 学校的课程作业windows SEH 机制简单入门windows 用户态 pwn / 内核态入门 计网实验报告 && 网安实验报告继续审计 nf_tables 源码&#xff0c;主要看 active 相关逻辑。复现 CVE-2022-32250 这个漏洞【 && iptables 相关学习】♥♥♥♥…

中介子方程九

X$XFX$XEXyXαXiX$XαXiXrXKXrXiXαX$XiXαXyXEX$XFX$XEXyXαXiX$XαXiXrXKXrXiXαX$XiXαXyXEX$XαXηXtXαX$XWXyX$XyXWX$XpXαXqXηX$XeXαXhX$XdX$XpX$XdX$XyXeXαX$XEXyXαXiX$XαXiXrXKXrXiXαX$XiXαXyXEX$XαXeXyX$XdX$XpX$XdX$XhXαXeX$XηXqXαXpX$XWXyX$XyXWX$XαXt…

基于vue的音乐播放器的设计与实现(论文+源码)_kaic

摘 要 当下&#xff0c;如果还依然使用纸质文档来记录并且管理相关信息&#xff0c;可能会出现很多问题&#xff0c;比如原始文件的丢失&#xff0c;因为采用纸质文档&#xff0c;很容易受潮或者怕火&#xff0c;不容易备份&#xff0c;需要花费大量的人员和资金来管理用纸质文…

【Qt秘籍】[010]-Qt常用控件

一、控件概述 在GUI&#xff08;图形用户界面&#xff09;开发领域&#xff0c;Qt无疑是众多开发者心中的首选框架之一。它不仅跨平台、功能强大&#xff0c;而且拥有丰富且灵活的控件库&#xff0c;使得开发者能够快速构建美观、高效的用户界面。对于初学者而言&#xff0…

C语言每日一题——分数加减(以最简形式输出)

请进行程序设计&#xff0c;以最简形式输出两个分数的加减运算结果。 输入包含多组测试数据&#xff0c;每组数据占一行&#xff0c;每行数据是一个字符串&#xff0c;格式为&#xff1a;"a/boc/d"。 其中a, b, c, d是一个0-9的整数。o是运算符""或者&quo…

GitLab代码导出 gitlab4j-api 实现

目录 GitLab简介 GitLab 的主要特点包括&#xff1a; GitLab代码导出 gitlab4j-api 添加 gitlab4j-api 依赖 使用 gitlab4j-api 获取特定命名空间下的所有项目 说明 注意事项 GitLab简介 GitLab 是一个开源的代码仓库和协作平台&#xff0c;主要用于版本控制和源代码管理…

2024年城市客运安全员考试题库及答案

一、单选题 161.依据《机动车强制报废标准规定》规定&#xff0c;小、微型出租客运汽车使用年限为&#xff08;&#xff09;年。 A.5 B.6 C.8 D.10 答案&#xff1a;C 162.依据《中华人民共和国道路交通安全法》&#xff0c;醉酒驾驶营运机动车的&#xff0c;由公安机关…

深度剖析整型和浮点型数据在内存中的存储(C语言)

目录 整型在内存中的存储 为什么整型在内存中存储的是补码&#xff1f; 大小端字节序 为什么有大端小端&#xff1f; 浮点型家族 浮点数在内存中的存储 long long 整型在内存中的存储 整型在内存中有三种二进制表示形式&#xff1a;原码&#xff0c;反码&#xff0c;补码…

Github 2024-06-10开源项目周报 Top15

根据Github Trendings的统计,本周(2024-06-10统计)共有15个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量Python项目8Jupyter Notebook项目2Go项目2C++项目1Shell项目1Lua项目1JavaScript项目1MDX项目1C项目1HTML项目1Python - 100天从新手到大师 创建…

列举常见的SQL语句

常见的SQL&#xff08;结构化查询语言&#xff09;语句用于管理&#xff08;如检索、插入、更新和删除&#xff09;关系型数据库中的数据。以下是一些常见的SQL语句示例&#xff1a; 数据查询&#xff08;SELECT&#xff09; 选择所有列和所有行 sql复制代码 SELECT * FROM 表…

关于目前ggrcs包的报错解决方案

目前有不少粉丝私信我说使用ggrcs包出现如下错误 我查看了一下&#xff0c;目前报错来源于新版本后的RMS包&#xff0c;主要是预测函数的报错&#xff0c;这个只能等R包作者来修复这个错误。目前需要急用的话&#xff0c;我提供了一个方案&#xff0c;请看下面视频操作 关于目前…

JWT理论介绍

文章目录 一、什么是JWT二、JWT的组成1.Header&#xff08;头部&#xff09;2.Payload&#xff08;负载&#xff09;3. Signature&#xff08;签名&#xff09; 三、为什么要使用JWT 一、什么是JWT JWT&#xff08;JSON Web Token&#xff09;是一个开放标准&#xff08;RFC 7…

GEE训练教程——如何确定几何形状的中心点坐标和相交的坐标

简介 在GEE中&#xff0c;可以使用.geometry()方法来获取几何形状的中心点坐标和相交的坐标。 首先&#xff0c;使用.geometry()方法获取几何形状的几何信息&#xff0c;然后使用.centroid()方法获取几何形状的中心点坐标。示例代码如下&#xff1a; // 获取几何形状的中心点…

家族企业如何找到合适的人才

家族企业似乎对外来的资源和活力会产生排斥作用。一般外来人员很难享受股权&#xff0c;其心态也永远只是打工者&#xff0c;始终难以融入组织中。 在80年代&#xff0c;家族企业靠胆识创业&#xff0c;90年代&#xff0c;靠经验发展&#xff0c;但在知识经济的今天&#xff0c…

ResourceManager 的 rpc server 模型

一. yarn ResourceManager 的三种通信协议 ResourceTrackerProtocol NodeManager 和 ResourceManager 的 RPC 通信协议。其中 ResourceManager 充当RPC Server的角色&#xff0c;而 NodeManager 充当 RPC Client 的角色。NodeManager 通过该协议向 ResourceManager 注册、汇报…