【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.mfbz.cn/a/695639.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows 10 找不到Microsoft Edge 浏览器

下载链接 了解 Microsoft Edge 手动下载浏览器 问题说明 一般来说&#xff0c;windows10系统应该是自带浏览器edge的&#xff0c;但有的电脑就是没有找到edge浏览器&#xff0c;可能系统是精简过的&#xff0c;可能是被卸载了。如下&#xff0c;控制面板确实没找到程序。 ​ …

笔记本充电出现了问题。

不知道为什么。电池充电图片一直显示的空。谁能救救我&#xff01;

C++命名空间的定义、C++命名空间的使用、C++输入输出等的介绍

文章目录 前言一、C命名空间的定义1. C命名空间产生的原因2. 作用域限定符3. C变量的访问顺序 二、C命名空间的使用1. 加命名空间名称及作用域限定符2. 使用using将命名空间中某个成员引入3. 使用using namespace 命名空间名称 引入4. 嵌套命名空间使用 三、 C输入&输出总结…

天才程序员周弈帆 | Stable Diffusion 解读(二):论文精读

本文来源公众号“天才程序员周弈帆”&#xff0c;仅用于学术分享&#xff0c;侵权删&#xff0c;干货满满。 原文链接&#xff1a;Stable Diffusion 解读&#xff08;二&#xff09;&#xff1a;论文精读 【小小题外话】端午安康&#xff01; 在上一篇文章天才程序员周弈帆 …

C#操作MySQL从入门到精通(14)——汇总数据

前言 我们有时候需要对数据库查询的值进行一些处理,比如求平均值等操作,本文就是详细讲解这些用法,本文测试使用的数据库数据如下: 1、求平均值 求所有student_age 列的平均值 string sql = string.Empty; if (radioButton_AVG.Checked) {sql = “select AVG( student_…

《Vue》系列文章目录

Vue (发音为 /vjuː/&#xff0c;类似 view) 是一款用于构建用户界面的 JavaScript 框架。它基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。无论是简单还是复杂的界面&#xff0c;Vue 都可以…

真北游记|三江交汇,碧海苍梧,端午去梧州吃龟苓膏

准备 t-14&#xff1a;高铁抢票&#xff08;A&#xff09; t-14&#xff1a;订行程(B)酒店&#xff08;C&#xff09; T-2&#xff1a;准备水、零食 T-1&#xff1a;物质准备&#xff1a;衣服、纸巾、毛巾、雨伞&#x1f302;、拖鞋、口罩&#x1f637;&#xff08;D&#xff0…

phpstudy的安装dvwa

phpstudy安装dvwa 1. 下载phpstudy Windows版phpstudy下载 - 小皮面板(phpstudy) (xp.cn) 2. 搭建dvwa靶场 下载地址&#xff1a;https://github.com/ethicalhack3r/DVWA/archive/master.zip 将其放入www文件夹中 3. 修改配置文件 将\DVWA-master\config中config.inc.php…

【深度揭秘】ChatGPT如何成为智能对话的领头羊?万字详解其背后的核心技术!

最近&#xff0c;OpenAI的预训练模型ChatGPT给人工智能领域的研究人员留下了深刻的印象和启发。毫无疑问&#xff0c;它非常强大&#xff0c;与之交流十分有趣&#xff0c;还能编写代码。它在多个方面的表现远超自然语言处理研究者的预期。因此&#xff0c;我们不禁要问&#x…

Nginx之正向代理配置示例和说明

一、NGINX正向代理功能简介 Nginx的正向代理功能允许局域网中的客户端通过代理服务器访问Internet资源。具体来说&#xff0c;Nginx作为一种流行的Web服务器和反向代理服务器&#xff0c;在正向代理方面的应用也相当实用。以下是其正向代理功能的几个关键点&#xff1a; 访问外…

[AI Google] 使用 Gemini 取得更多成就:试用 1.5 Pro 和更多智能功能

总结 Google 正在为超过 35 种语言的 Gemini Advanced 订阅者推出 Gemini 1.5 Pro。此次更新包括 100 万个 token 的上下文窗口、改进的数据分析功能和增强的多模态图像理解。新功能包括用于自然对话的 Gemini Live、先进的规划工具和可定制的 Gems。更新还集成了更多 Google …

【Python项目】——爬虫爬取柯南的剧集数和集名(有错求指点)

项目目的&#xff1a;因为柯宝除了在CSDN写博客这一爱好外&#xff0c;还比较喜欢追番剪辑&#xff0c;尤其是柯南&#xff0c;想到了爬取这个&#xff01;&#xff01;参考Github大佬&#xff0c;原项目链接&#xff1a; 原作者Githubhttps://github.com/LorentzForceWorkEnz…

博客摘录「 AXI三种接口及DMA DDR XDMA介绍(应用于vivado中的ip调用)」2024年6月10日

关键要点&#xff1a; 1.AXI Stream经过协议转换可使用AXI_FULL&#xff08;PS与PL间的接口&#xff0c;如GP、HP和ACP&#xff09;。 2.传输数据类里就涉及一个握手协议&#xff0c;即在主从双方数据通信前&#xff0c;有一个握手的过程。基本内容&#xff1a;数据的传输源会…

Docker与Docker-Compose详解

1、Docker是什么&#xff1f; 在计算机中&#xff0c;虚拟化(英语: Virtualization) 是一种资源管理技术&#xff0c;是将计算机的各种实体资源&#xff0c;如服务器、网络、内存及存储等&#xff0c;予以抽象、转换后呈现出来&#xff0c;打破实体结构间的不可切割的障碍&…

【服务实现读写分离】

文章目录 什么是读写分离基于Spring实现实现读写分离项目中常用的数据源切换依赖包 什么是读写分离 服务读写分离&#xff08;Service Read-Write Splitting&#xff09;是一种常见的数据库架构设计模式&#xff0c;旨在提高系统的性能和可扩展性。通过将读操作和写操作分离到…

ChatTTS改良版 - 新增精选高品质音色,新增超长文本推理,新增api接口

这个版本是ChatTTS的一个分支&#xff0c;基于ChatTTS修改&#xff0c;由6drf21e大佬改良&#xff0c;大佬GitHub地址 GitHub - 6drf21e/ChatTTS_colab: &#x1f680; 一键部署&#xff08;含离线整合包&#xff09;&#xff01;基于 ChatTTS &#xff0c;支持音色抽卡、长音频…

SpringBootWeb 篇-深入了解 Redis 五种类型命令与如何在 Java 中操作 Redis

&#x1f525;博客主页&#xff1a; 【小扳_-CSDN博客】 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 Redis 概述 1.1 Redis 下载与安装 2.0 Redis 数据类型 3.0 Redis 常见五种类型的命令 3.1 字符串操作命令 3.2 哈希操作命令 3.3 列表操作命令 3.4 集合操作命令 …

【面试干货】 B 树与 B+ 树的区别

【面试干货】 B 树与 B 树的区别 1、B 树2、 B 树3、 区别与优缺点比较4、 总结 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在数据库系统中&#xff0c;B 树和 B 树是常见的索引结构&#xff0c;它们在存储和组织数据方面有着不同的设计…

树莓派4B 零起点(三) 树莓派 VNC 远程桌面配置(1)

目录 一、启用树莓派4B的 VNC 服务 二、在PC的操作系统上安装VNC客户端 1、下载安装 RealVNC 2、下载安装 TigerVNC 三、登录VNC远程桌面 1、通过使用 ifconfig 查看树莓派的 IP 地址 2、启动 TigerVNC 客户端&#xff08;Windows版本演示&#xff09; 在前两章的基础下…

【C++修行之道】类和对象(六)再谈构造函数(初始化列表)| explicit关键字 | static成员 | 友元|匿名对象|拷贝时一些编译器优化

目录 一、再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1. 所有的成员,既可以在初始化列表初始化,也可以在函数体内初始化 2. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次) 3. 类中包含以下成员&#xff0c;必须放在初始化列表位置进行初始化&…