linux入门---环境变量

目录标题

  • 指令的本质
  • 如何不加./
    • 方法一
    • 方法二
  • 环境变量的重置
  • 在命令行上查看环境变量
  • 为什么会存在环境变量
  • 在程序中查看环境变量
  • 本地变量和环境变量
  • 环境变量的继承

指令的本质

在使用linux的时候我们经常会使用很多指令比如说:ll指令,pwd指令,whoami指令等等,不同的指令都对应着不同的功能:
在这里插入图片描述
我们平时也会写一些c语言文件,再通过gcc编译器将这些文件生成一个可执行程序,比如说这里的myproc.c文件这个文件里面就写着一些c语言代码:
在这里插入图片描述
myproc是一个可执行程序这个程序是由文件myproc.c编译生成的,并且这个程序运行的结果就是不停的打印这个进程的PID是多少方便我们执行其他的操作:
在这里插入图片描述
那这里能不能换个方式来描述一下myproc可执行程序,我们说这个程序的功能是循环打印处本进程的PID,如果这么描述的话大家有没有发现一些相似之处,我们说执行不同的指令就是执行不同的功能,而运行可执行程序也是执行对应的功能,那我们能不能说平时使用的指令就是一个个的可执行程序呢能不能平时我们写的可执行程序也是一个指令呢?答案是可以的我们通过file指令就可以看到平时使用的指令都是可执行程序:
在这里插入图片描述
但是这里就有一个问题:我们写的文件是可执行程序,操作系统自带的指令也是可执行程序,那为什么运行自己写的可执行程序的时候得在前面加上./而系统中的指令却不用呢?原因很简单当我们在操作系统上执行可执行程序的时候得告诉操作系统这个程序在哪里,而./就是告诉操作系统你要执行的程序就在当前路径下,如果我们将当前的路径进行修改改成上一层路径再想执行myproc程序的话就不能使用./myproc而是./folder2/myproc
在这里插入图片描述
执行操作系统内部的指令之所以不用添加路径是因为系统中定义了一个全局变量PATH,这个变量里面记录了内部指令所在的路径当我们运行可执行程序没用添加路径的时候,系统就会默认在PATH记录的地址中去寻找并执行该程序,我们可以通过echo $PATH指令来查看PATH变量记录的值:
在这里插入图片描述
仔细观察一下就可以看到这个变量记录了多个地址并且不同的地址通过:进行隔开。

如何不加./

方法一

不加路径执行程序的时候操作系统会在PATH记录的默认路径下查找对应的程序,那如果我们把自己写的程序添加到PATH所指向的路径之一的话,那我们在执行该程序的时候是不是就不用添加相对路劲了呢?我们来看看下面的操作
在这里插入图片描述
这里执行失败是因为将程序拷贝到那个路径下得提权普通用户是没用权限的,我们再来操作一次:
在这里插入图片描述
就可以发现myproc程序不添加相对路径也可以正常执行,但是这种方法不推荐大家使用因为你写的程序不一定安全将不安全的程序添加到这些路径下可能会存在风险,所以我们一般采用第二种方法。

方法二

方法一是将程序添加到PATH里面的路径中,那么方法二就是将该程序所处的路径添加到PATH变量里面,但是这里大家要注意一点将程序的地址添加到PATH变量里面是指令export PATH=$PATH:/程序所在的路径/而不是export PATH =/程序所在的路径/,因为第二个方法所造成的的结果是让PATH的值变成了你的路径,而不是将你的路径添加上去比如说下面的操作:
在这里插入图片描述
而使用第二种指令之后变量PATH的内容会被你添加的地址所覆盖:
在这里插入图片描述
那么这里大家要注意一下。

环境变量的重置

如果大家在命令行中一不小心将环境变量的内容修改了的话,请大家不要慌因为你重新登录一下就可以发现之前修改的环境变量又变回了之前的值,比如说上面修改了环境变量PATH但是重新登录一下就可以看到PATH的内容被复原了
在这里插入图片描述
这是因为在家目录下有这.bash_profile和.bashrc这两个文件

在这里插入图片描述
打开.bash_profile文件可以看到下面的内容
在这里插入图片描述
我们来看看下面这段代码

 if [ -f ~/.bashrc ]; then
   . ~/.bashrc

这段代码是一个shell脚本,-f ~/.bashrc的意思就是检测.bashrc文件是否存在,如果存在的话就执行下面的代码:
~/.bashrc这段代码的意思就是执行.bashrc文件里面的内容,在这个文件的下方还有一段代码就是:

PATH=$PATH:$HOME/.local/bin:$HOME/bin
 export PATH

这段代码干的事情就是创建环境变量PATH并往这个变量里面导内容,我们再打开.bashrc文件
在这里插入图片描述
就可以看到这个文件里面也会检测系统的bashrc文件是否存在,如果存在的话就会执行这个文件同时在这个文件的下方也会创建环境变量和导环境变量,我们打开系统的bashrc文件看看里面有什么内容:
在这里插入图片描述
我们看到这个文件里面有非常多的内容,但是这么多内容他的目的却只有一个就是帮我们创建环境变量并导环境变量,这个文件的内容大家肯定是看不懂的,但是大家得知道一件事就是每次登录用户的时候操作系统会自动地执行.bash_profile文件里面地内容,在.bash_profile文件里面会创建并导一些环境变量然后在执行.bashrc文件里面地内容,在.bashrc文件里面会创建并导一些环境变量然后执行系统的bashrc文件里面的内容,而系统的这个文件里面也会执行其他文件的内容并创建一些环境变量,所以我们每次登录用户时环境变量都会被重新创建并初始化为一个固定值,希望大家可以理解。

在命令行上查看环境变量

使用指令env就可以查看所有的环境变量;
在这里插入图片描述
其中环境变量HOME就是记录当前用户的家目录:
在这里插入图片描述
环境变量HOSTNAME就储存着主机名
在这里插入图片描述
环境变量HISTSIZE中就记录了操作系统所能记录的最大历史指令数为3000
在这里插入图片描述
当然这里的环境变量还有很多这里我们就不一一介绍大家可以自行了解。

为什么会存在环境变量

大家有没有想过一个问题:在命令行上输入pwd指令为什么会显示程序当前所在的路径?输入whoami指令的时候linux怎么知道当前使用登录机器的用户是谁?在命令行输入指令的时候linux为什么能够知道这些指令所在的位置在哪里?linux怎么知道你当前使用的shell种类是什么?linux怎么知道当前的各种配置方案所用的编码方式是什么?记录历史指令的最大指令条数是什么和各种动静态库头文件的搜索路径在哪?等等问题上面问题涉及着Linux的不同的领域,有的涉及着查找指令的,有的涉及登录用户是谁的,有的是确认登录主机名是谁的,有的是确认使用shell种类的,那么为了解决上面各种各样的问题,操作系统就得在启动bash的时候给我们做命令行解释解释器的时候设置好一批未来要用到的全局变量,这批变量我们就将其称之为环境变量,环境变量是操作系统为了满足不同的应用场景预先在系统内设置的一大批的全局变量,这些变量在整个系统当中从bash往后都会被其他的进程所访问到,不同的环境变量都有着它不同的用途,比如说环境变量HOME就是记录着当前用户的家目录所以在命令行上使用cd ~的时候可以直接将当前路径切换到家目录下,cd ~就直接变成了cd HOME,环境变量HOSTNAME储存着主机名所以Linux可以知道当前使用机器的主机名,环境变量PWD时时刻刻记录着的当前所在路径所以在使用pwd指令的时候可以在屏幕上显示当前所在的路径,那么这就是环境变量存在的意义它可以帮助操作系统解决一些不停领域上的问题。

在程序中查看环境变量

在命令行上可以通过指令env来查看有哪些环境变量以及环境变量的内容,那么在我们写的程序里面也可以通过函数getenv来获取你指定的环境变量,我们来看看这个函数的功能介绍:
在这里插入图片描述
该函数的参数是一个字符指针返回值也是一个字符指针,如果你先查看环境变量PWD的内容的话就可以使用getenv函数并把字符串"PWD"传给这个函数,该函数就会返回一个指向环境变量的内容的指针,比如说下面的代码:
在这里插入图片描述
这段代码的运行结果如下:
在这里插入图片描述

如果我们想查看环境变量USER的内容的话就可以把字符串"USER"传递给这个函数:
在这里插入图片描述
这段代码的运行结果如下:
在这里插入图片描述
当然这里只是该函数的一个使用方面将内容打印到屏幕上面,我们还可以使用该函数在程序里面实现其他的功能,比如说当前的程序可以打印出来使用者的名字:我们当前的用户是xbb所以打印出来的是xbb,
在这里插入图片描述如果我们切换成其他的用户再执行这个程序的话打印出来的结果也就是其他用户的名字,按下ctrl+D先退出当前用户再重新登录一下就可以看到当前的用户变成了root:
在这里插入图片描述
也就是说不同的用户执行同一个程序会有不同的结果,原因就是用户所对应的环境变量的内容是不一样的,那这里大家想一下之前学习的权限,我们说不同的人有不同的权限,没有权限的人是无法查看或者使用或者修改别人的文件,那这里的权限不就通过环境变量来实现的嘛?通过getenv函数可以得到环境变量USR的内容,而不同的用户所对应的环境变量的内容又是不一样的,那如果这个文件只想让root用户运行的话是不是就可以使用getenv函数加if语句的形式来实现这里的权限,比如说下面的代码:
在这里插入图片描述
当前的用户是xbb所以这个程序执行的结果就是告诉我们没有权限
在这里插入图片描述
如果我们将用户修改成root,那么这个程序就可以正常执行:
在这里插入图片描述
那么这就是getenv函数的作用希望大家能够理解。

本地变量和环境变量

我们可以在命令行上定义环境变量比如说下面的操作:
在这里插入图片描述
并且还可以通过echo指令显示这个环境变量的内容:
在这里插入图片描述
但是这里虽然能够通过echo显示这个环境变量的内容,但是我们env指令却找不到这个任何关于myval的内容:
在这里插入图片描述
之所以出现这样的现象是因为通过该方式创建的变量不是环境变量而是本地变量,本地变量只能在当前进程中使用在其他进程中是无法使用的,就好比c语言中的全局变量和局部变量。通过指令set可以查看所有的环境变量和本地变量,由于本地变量的内容非常的多所以使用set指令的时候一般搭配着grep指令一起使用,比如说下面的操作:
在这里插入图片描述
使用export指令可以将本地变量的内容导到环境变量里面去该指令的使用形式为:export + 本地变量名比如说下面的操作:
在这里插入图片描述
当然也可以使用export指令直接创建环境变量:
在这里插入图片描述
如果想要删除环境变量里面的本地变量的话就可以使用指令unset其形式为:unset 变量名比如说下面的操作:
在这里插入图片描述
当然使用这个指令也可以删除本地变量比如说下面的操作:
在这里插入图片描述

环境变量的继承

我们在上面说过环境变量具有全局属性在所有的进程中都可以使用,而本地变量没有全局属性只能在当前进程中被使用,就好比c语言中的全局变量和局部变量那我们这里我们可以通过下面的操作来证明这一点:首先创建一个环境变量myval和一个本地变量myval1:
在这里插入图片描述
因为如果使用getenv函数没有找到对应的环境变量的话就返回一个空指针,所以我们可以根据这个函数的返回值来写一段下面的函数:
在这里插入图片描述

在命令行执行一个程序本质上是创建一个子进程让子进程来完成这个程序,环境变量的内容是全局变量所以在子进程中可以被使用,而本地变量的内容不是全局变量所以子进程中是无法打印出本地变量的值的所以这段代码的运行结果如下:
在这里插入图片描述
那这里就有个问题环境变量是如何做到全局属性的呢?为什么要有全局属性呢?原因很简单我们知道bash是一个系统进程,我们执行的myproc程序会通过fork函数变成bash的子进程,而全局变量之所以具有全局属性是因为bash的环境变量会被子进程继承下去,所以这也是为什么myval可以在子程序myproc中找到而myval1却找不到的原因,那为什么子进程要继承父进程的环境变量的原因呢?答案是为了不同的应用场景比如说让bash帮我们找指令的路径,身份认证等等等,这些都是要继承环境变量的原因希望大家能够理解。

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

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

相关文章

Java JDK详细安装配置(详细备忘版本)

目录概览一、下载安装二、环境配置三、常见问题一、下载安装 官方下载地址:点我去官网 java20 、java17如下: java8、java11如下 jre8 如下 以 java8 下载为例: 按步骤输入账号密码 之后就会跳出下载显示框 得到了文件名为 jdk-8u361-win…

单机分布式一体化是什么?真的是数据库的未来吗,OceanBase或将开启新的里程碑

一. 数据 我们先说说数据这个东西,这段时间的ChatGPT在全世界的爆火说明了一件事,数据是有用的,并且大量的数据如果有一个合适的LLM大规模语言模型训练之后,可以很高程度的完成很多意想不到的事情。 我们大多数的时候的注意力只…

class03:MVVM模型与响应式原理

目录一、MVVM模型二、内在1. 深入响应式原理2. Object.entries3. 底层搭建一、MVVM模型 MVVM,即Model 、View、ViewModel。 Model > data数据 view > 视图(vue模板) ViewModel > vm > vue 返回的实例 > 控制中心, 负责监听…

ChatGPT使用介绍、ChatGPT+编程、相关组件和插件记录

文章目录介绍认识ChatGPT是通过英汉互译来实现中文回答的吗同一个问题,为什么中英文回答不同ChatGPT的使用对话组OpenAI APIAI智能绘图DALLE 2ChatGPT for Google插件ChatGPT编程编写代码代码错误修正与功能解读代码评审与优化推荐技术方案编写和优化SQL语句在代码编…

Spring Boot集成RocketMQ实现普通、延时、事务消息发送接收、PULL消费模式及开启ACL | Spring Cloud 30

一、前言 在前面我们通过以下章节对RocketMQ有了基础的了解: docker-compose 搭建RocketMQ 5.1.0 集群(双主双从模式) | Spring Cloud 28 docker-compose 搭建RocketMQ 5.1.0 集群开启ACL权限控制 | Spring Cloud 29 现在开始我们正式学习…

蓝桥杯 - 求组合数【C(a,b)】+ 卡特兰数

文章目录💬前言885. 求组合数 I C(m,n) 【dp】886 求组合数 II 【数据大小10万级别】 【费马小定理快速幂逆元】887. 求组合数 III 【le18级别】 【卢卡斯定理 逆元 快速幂 】888.求组合数 IV 【没有%p -- 高精度算出准确结果】 【分解质因数 高精度乘法 --只用一…

5.5G产业再提速!高通5GAdvanced-ready芯片商用终端下半年面世

MWC2023大会召开在即,5GAdvanced产业再添重磅消息!2月15日,高通宣布推出全球首个5GAdvanced-ready基带芯片——骁龙X755G调制解调器及射频系统,支持毫米波和Sub-6GHz频段,带来网络覆盖、时延、能效和移动性等全方位的提…

【C语言】深度理解指针(下)

一. 前言💎昨晚整理博客时突然发现指针还少了一篇没写,今天就顺便来补一补。上回书说到,emmm忘记了,没事,我们直接进入本期的内容:本期我们带来了几道指针相关笔试题的解析,还算是相对比较轻松的。话不多说…

RTL8201 以太网PHY芯片 调试记录

一、概述 为了尽量给甲方降低成本,决定使用较低成本的PHY芯片RTL8201F-VB-CG芯片。移植官网的以太网demo程序,git上下载了一份很好看的rtl8201F的驱动程序,用来替换官方demo的lan8742程序。并没有直接通,于是开始了调试之路。 二…

mysql索引类型有哪些?

在Mysql数据库当中,我们经常会谈到Sql语句,当然也会谈到索引优化,那么在数据库当中有哪些索引类型呢,博主在这里进行分享,希望对大家能有所帮助。 目录 1、B-Tree索引: 2、Hash索引: 3、Full…

SpringBoot 将PDF转成图片或World

SpringBoot 将PDF转成图片或World 准备工作Apache PDFBox将PDF转成一张图片将PDF转成多张图片将PDF转成其他文件格式总结SpringBoot 是一款非常流行的 Java Web 开发框架,可以用来构建各种 Web 应用程序。在本篇博客中,我们将介绍如何使用 SpringBoot 将 PDF 转换成图片或其他…

Elasticsearch 学习+SpringBoot实战教程(三)

需要学习基础的可参照这两文章 Elasticsearch 学习SpringBoot实战教程(一) Elasticsearch 学习SpringBoot实战教程(一)_桂亭亭的博客-CSDN博客 Elasticsearch 学习SpringBoot实战教程(二) Elasticsearch …

第十四届蓝桥杯三月真题刷题训练——第 23 天

目录 第 1 题:长草 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码: 思路: 第 2 题:蓝肽子序列_LCS_最长公共子序列dp问题 题目描述 输入描述 输出描述 输入输出样例 运行限制 代码: 思路&am…

Spring源码面试最难问题——循环依赖

前言 问:Spring 如何解决循环依赖? 答:Spring 通过提前曝光机制,利用三级缓存解决循环依赖(这原理还是挺简单的,参考:三级缓存、图解循环依赖原理) 再问:Spring 通过提前…

【前沿技术】问答pk【ChatGPT Vs Notion AI Vs BAT AI 】

目录 写在前面 问题: 1 ChatGPT 1.1 截图 ​1.2 文字版 2 Notion AI 2.1 截图 2.2 文字版 3 BAT AI 3.1 截图 3.2 文字版 总结 序言 所有幸运和巧合的事,要么是上天注定,要么是一个人偷偷的在努力。 突发奇想,问三个…

③【Java组】蓝桥杯省赛真题 持续更新中...

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ 蓝桥杯真题--持续更新中...一、错误票据题目描…

CCF-CSP认证 202303 500分题解

202303-1 田地丈量&#xff08;矩阵面积交&#xff09; 矩阵面积交x轴线段交长度*y轴线段交长度 线段交长度&#xff0c;相交的时候是min右端点-max左端点&#xff0c;不相交的时候是0 #include<bits/stdc.h> using namespace std; int n,a,b,ans,x,y,x2,y2; int f(in…

用CSS3画了一只猫

感觉我写得技术含量不高&#xff0c;全都是用绝对定位写的&#xff0c;一定会有更好的&#xff0c;代码量更少的做法吧 <!DOCTYPE html> <html> <head><title>Cute Cat</title><style type"text/css">*{box-sizing: border-box…

100天精通Python(可视化篇)——第81天:matplotlib绘制不同种类炫酷饼图参数说明+代码实战(自定义、百分比、多个子图、圆环、嵌套饼图)

文章目录专栏导读0. 前言1. 参数说明2. 普通饼图3. 百分比饼图4. 突出某一块的饼图5. 自定义颜色的饼图6. 多个子图7. 圆环饼图8. 圆环分离饼图9. 饼图圆环图组合10. 多层圆环饼图专栏导读 &#x1f525;&#x1f525;本文已收录于《100天精通Python从入门到就业》&#xff1a…

【VScode】远程连接Linux

目录标题1. 安装扩展插件2. 在Linux上操作3. 确定Linux的IP地址4. 远程连接到Linux5. 实现免密码登录使用 VScode 远程编程与调试的时有会用到插件 Remote Development&#xff0c;使用这个插件可以在很多情况下代替 vim 直接远程修改与调试服务器上的代码&#xff0c;同时具备…