linux-15 关于shell(十四)printenv,hash,环境变量

news2025/3/1 18:13:48

    此前没有用过linux,可能有些觉得很奇怪,就觉得我们在这敲来敲去命令干什么?为什么不使用双击这种方式来操作?大家知道,在Windows里面,其实我们双击也无非就是告诉我们shell需要将这个命令发送在内核上启动的,是不是这样子?那只不过采用另外一种操作方式而已。但是各位有没有发现我们刚才执行ls的时候?我们执行ls的时候压根就没说这是哪个路径的ls。发现了吗?那它怎么知道是在bin下呢?还有我们执行su的时候,也没告诉他我们到底su到哪个或者这个命令在什么地方,为什么我们当前系统能找到?这两个命令,按道理来讲,我们引用任何一个文件都必须给它一个全路径,你比如说ls应该使用bin下的ls,这才合适。但是我们却没有带,这是为什么?大家应该知道,如果我们使用每一个命令,都要带上路径的话,这是会非常繁琐,对吧?使得我们本来使用命令就容易兴趣可能就大减。
    那因此,系统为了能够便捷的让用户在命令提示符下执行命令,它给我们内置了一种机制,这种机制是通过所谓的一个叫做环境变量的方式来实现的。我不知道各位有没有听说过环境变量。什么叫环境变量?首先问一下,什么叫变量?变量是什么?我们很多时候都在使用变量,你有没有想过变量到底是什么?是个容器没错,什么容器?存放数据的容器。
    那容器在什么地方呢?有没有想过这个问题?变量是什么?说白了,变量其实是内存,变量是命名的内存空间,我在空闲的内存里边画出来一个k,给它起个名,然后我就可以向这个起了名的内存空间中放数据了,这个放数的过程叫变量赋值,记得吗?很多写过程序的知道,什么叫赋值吧比如说,name=jerry,我起个变量叫name,我写个name等于jerry,这什么意思?在内存中找一段空间起名叫做name,而这个空间中放的数据叫做jerry懂了吧?所以这个等于号是表示赋值,在这里边存数据的意思,那为什么说它叫变量呢?因为我可以给它改改,它里边本来存的是jerry,我再name=tom,那里边名就是什么?差不多就这么简单。
    假设我们教室里摆了十个箱子,箱子是不是都是容器啊?给箱子取上名,一号箱二号箱,我说一号箱放书,明白了吗?就这意思,当然这个名称一定要记得,只在当前程序中有用,你把这个程序一换,那名称可能是另外一个内存空间了。
    而且变量可以申请使用,当我们用完以后,还可以把它释放或者叫撤销都行。
那这张内存空间还给系统了,还可以分配给其他的程序使用的意思,那因此声明变量的过程就是让程序告诉操作系统,给我一个内存,我会要放数据,所以,变量声明的过程,也就是申请内存使用的过程。有没有听说过堆栈的概念?什么是堆?呃,可能就一愣是吧?堆和栈还能分开说吗?
那什么是栈?在编程当中,堆叫做heap,栈叫做stack,他们其实是用来放各自不同类型的数据的,比方说在战栈当中,通常本地声明的一些变量,静态变量等等都在栈里边,而其他用来获取申请保存数据的地方不是变量,但需要保存数据。比如我打开一个文件,这个文件要被程序访问,必须要放入内存的,这时候它不是变量,只是申请到内存空间进行放置,一般都是用堆来进行存放,
所以它是内存申请和分布的两种不同机制,而且在进程地址空间中也是不同的,接下来,我们还要再进行细讲。

    好了,现在咱不扯那么远,回头讲shell教学编程的时候会细讲变量类型的,那现在我们先回来说什么叫环境变量?有没有留意过在Windows里边?虽然装的都是win7,可以设的桌面不一样,是不是?甚至说,我同一个计算机上两个用户的桌面,是不是也可以不一样?主题也可以不一样,等等,那有没有想象过,为什么对这些人来讲,可以不一样呢?还有这些信息对一个用户来讲,保存在什么地方?为了能够达到换某个技能的效果,可以用一个属性来指定使用哪种效果,是不是这意思?那假如说,张三指定我使用海洋主题,李四指定使用沙漠主题,那结果绝对不一样,对吧?
那这个主题的内容,我们应该在什么地方进行定义?想到过吗?那肯定,每个人都有一个配置文件,叫做软件的文件,这个文件中可以定义我们到底使用什么的,这能理解吧,
但只不过我们平时没有打开文件编辑过,都是在什么?比如填个字符,下一步填个字符,下一步对不对?实际上这些内容都保存一个文件当中的,这种文件我们可以把它理解成叫程序的配置文件。
而在这个配置文件中,通常就有一个变量名等于什么,来定义它所使用的那个文件或者主题叫什么名字?而这里的最终结果是显示的用户的桌面环境不相同,是不是可以把它理解成环境变量,
可以这么理解,但是事实上环境变量还有另外一层含义,这个我们回头再说。那于是我们可以理解成,环境变量就是用于定义当前用户的工作环境的,指定的工作环境属性的,我可以定义主题跟别人不一样,可以定义我的显示的用户的logo头像跟别人不一样,还可以显示我们使用的字体,默认字体跟别人不一样,这是不是有很多属性可以定义啊?每一个属性的定义都是用一个变量或者一个叫做环境变量进行定义,能理解了吗?那事实上,无论是哪一种shell,它都应该有自己的环境变量的,你无论是bash、csh,甚至是桌面环境,都一个道理,就是因为定义当前用户的环境显示结果,当然虽然这样讲有些直白,甚至于不太确切,足以能说明问题了。
    好,那因此,对于当前系统来讲,或者对于当前shell来讲,它就有许多环境变量了,
比如说,各位来看一下,我使用printenv,因为environment,环境的意思,那printenv就是显示环境,如下图,

看到了吗?那是不是都是变量?而且还显示了变量等于什么,就表示变量给它赋个什么值,像HOSTNAME,主机名,TERM这是什么?终端类型,shell表示什么?你使用的shell程序是什么?看到没有?能理解了吧,但是我们现在要说的是这个PATH,path环境变量,它就是一堆使用冒号隔开的路径,使用冒号分割的一堆路径。当我们执行ls命令的时候,它会按次序从这些指定路径下,一个一个去找,先找这个/usr/kerberos/sbin,看有没有叫ls的可执行程序,这个路径下没有找到,然后再找下一个,直到第一次找到有ls命令的位置,明白吗?第一次找到它为止,那因此,如果你两个地方都有ls,这两个路径谁在前头就用谁的。

    想一个问题,如果我需要执行许许多多的命令,但是如果每一次都要查找一遍,大家知道,虽然计算机执行速度很快,但如果每一次都找,是不是也很慢?事实上,在我们系统上有成千上万个命令,那所以如果某一个命令第一次执行的时候,它一定是实时去找的,如果找着了,第二次再执行就不找了,它就不再找了。为什么?它怎么不再找了呢?有个缓存,会有一个缓存在内存中找一个地方,把这个命令和它对应的路径给缓存下来。这个命令有个命令叫做hash,如下图,

看看里边记录下来,有没有你的ls,在什么地方?看到没有,而且你的ls命中了多少次,那hash是什么呢?它是一种缓存,你可以把它理解成是一种缓存,只有缓存才有命中的概念。所以bash自己内置的还有一个缓存,在缓存中记录下来了此前所用过的所有命令的路径,并且以后每一次在用的时候就不会再去找了,而直接先找这个缓存。那很奇怪,找缓存和找路径不是一个概念吗?反正都在找啊,对不对?那有什么不同呢,一定要记得缓存这种思想,在计算机发展历史上叫做缓存为王,cache is king,当任何时候,计算机的某一个系统速度慢了,就通过加缓存来实现,所以缓存这种概念,以后我们会不停的使用缓存,各个系统都会有缓存的,所以这个概念大家一定要理解,好,缓存下来,有什么效果,以后我们再用的时候,不是直接去找内容,是先看缓存中有没有,是这意思?那缓存下来,如果内容非常多的话,刚才说过,找缓存的速度,难道一定会比直接找文件的速度快吗?会不会?一定要记得,缓存在这里,它保存的是一个hash列表,有听说过吗?叫哈西是吧,hash是一个键值对,是一个键值就叫k-value,它是一个键值数据库,在键值库当中查找内容的速度是O(1)的。什么是O(1)?这是衡量一个程序执行速度的一种标准,它的意思是从一个列表中查找一个数据的速度随着列表长度变化而发生变化的比例,或者叫函数趋势。这叫O,那么O(1)指的是什么呢?无论你这个队列有多长,我从中找一个内容的时间是一样的,从一个中去找和从一万个中去找,所花费的时间一样。所以说hash是O(1)的,因此hash表中找,无论再长,瞬间就可以找到它,就这么快,因为它是单一比较的,因为它是有索引的,这跟在文件系统中一个一个找比起来,速度绝对是快了不止一倍,甚至不止万倍。所以说缓存是实现系统加速的,这种概念以后学习中会反复的强调,先有个印象就可以了。所以这就是它为什么要保存起来的原因。好,我们使用hash命令可以看到这个缓存,那我们要想清空这个缓存也是可以的,那至于怎么我们反过来说,你先知道hash这个命令就行了。

    好,先知道path环境变量,这也是非常关键的注意,这是使用冒号隔开的一堆路径,而且这冒号所给它的这个路径的次序也很关键。当然了,如果将来我们自己开发了一个程序,放在了某个路径下,而那个路径不在path路径当中,我们直接执行,如果不跟路径的话,它能执行吗?所以我们所有的命令,只要不带路径,它一定得是path指定路径上的文件,如果不是就无法执行,所以要么给它一个完整路径,要么是把那个命令所在路径给它加到path中来。好,这就是我们整个命令,它们彼此间的关系。实际上bash还有很多属性,这些属性是什么?我们下回再说!

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

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

相关文章

虚拟机如何使用物理机的公私钥

一、生成公私钥(如果没有的话) 使用如下指令生成 生成RSA公私钥 ssh-keygen 生成EdDSA公私钥 ssh-keygen -t ed25519 Windows目录 linux会直接生成在当前目录下。 二、导出 一般都是从windows系统导入到linux系统。 可以直接将公私钥文件复制到虚拟机…

SpringBoot【十一】mybatis-plus实现多数据源配置,开箱即用!

一、前言🔥 环境说明:Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 正常情况下我们在开发系统的时候都是使用一个数据源,但是由于有些项目同步数据的时候不想造成数据库io消耗压力过大,便会一个项目对应多个数据源…

前端报错npm ERR cb() never called问题

环境使用node版本v14.21.3&#xff0c;npm版本6.14.18 1.问题描述 1.1使用npm install后报错 npm ERR! cb() never called!npm ERR! This is an error with npm itself. Please report this error at: npm ERR! ? ? <https://npm.community>npm ERR! A complete log…

C++ STL Cookbook STL算法

目录 std::copy 将容器元素合并为一个字符串 使用 std::sort 对容器进行排序 使用 std::transform 修改容器 在容器中查找项目 使用 std::sample 采样数据集 (写在前面&#xff1a;笔者前段时间备战考试和比赛了&#xff0c;现在回来继续更新) STL实际上提供了非常非常丰…

SpringBoot【十】mybatis之xml映射文件>、<=等特殊符号写法!

一、前言&#x1f525; 环境说明&#xff1a;Windows10 Idea2021.3.2 Jdk1.8 SpringBoot 2.3.1.RELEASE 在利用mybatis进行开发的时候&#xff0c;编写sql时可能少不了>、<等比较符号&#xff0c;但是在mapper映射文件中直接使用是不行的&#xff0c;会报错&#xff0…

单元测试SpringBoot

添加测试专用属性 加载测试专用bean Web环境模拟测试 数据层测试回滚 测试用例数据设定

每天40分玩转Django:简介和环境搭建

Django简介和环境搭建 一、课程概述 学习项目具体内容预计用时Django概念Django框架介绍、MVC/MTV模式、Django特点60分钟环境搭建Python安装、pip配置、Django安装、IDE选择45分钟创建项目项目结构、基本配置、运行测试75分钟实战练习创建个人博客项目框架60分钟 二、Djang…

Jenkins参数化构建详解(This project is parameterized)

本文详细介绍了Jenkins中不同类型的参数化构建方法&#xff0c;包括字符串、选项、多行文本、布尔值和git分支参数的配置&#xff0c;以及如何使用ActiveChoiceParameter实现动态获取参数选项。通过示例展示了传统方法和声明式pipeline的语法 文章目录 1. Jenkins的参数化构建1…

Windows安装WSL子系统及docker,以及WSL和docker配置、使用及问题解决

在Windows操作系统中,Ubuntu子系统(也称为Windows Subsystem for Linux, WSL)为开发者提供了一个在Windows环境下运行Linux环境的平台。然而,有时用户在按照Ubuntu子系统或者使用WSL时,可能会遇到各种问题,下面总结一下解决方式。 想要在Windows上安装Docker(实际上是基…

Linux中的线程

目录 线程的概念 进程与线程的关系 线程创建 线程终止 线程等待 线程分离 原生线程库 线程局部存储 自己实现线程封装 线程的优缺点 多线程共享与独占资源 线程互斥 互斥锁 自己实现锁的封装 加锁实现互斥的原理 死锁 线程同步 线程的概念 回顾进程相关概念 …

shell编程(完结)

shell编程&#xff08;完结&#xff09; 声明&#xff01; 学习视频来自B站up主 ​泷羽sec​​ 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章 笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其…

ctfshow-web 151-170-文件上传

151. 我们首先想到就是上传一句话木马。但是看源代码限制了png。 &#xff08;1&#xff09;改前端代码。 这里是前端限制了上传文件类型&#xff0c;那我们就改一下就好了嘛,改成php。 这里直接修改不行&#xff0c;给大家推荐一篇简短文章&#xff0c;大家就会了&#xff08…

Docker的初识

目录 1. 容器技术发展史1.1 Jail 时代1.2 云时代1.3 云原生时代1.3.1 Google & Docker 竞争1.3.2 k8s 成为云原生事实标准 2. 虚拟化和容器化的概念2.1 什么是虚拟化、容器化2.2 为什么要虚拟化、容器化&#xff1f;2.3 虚拟化实现方式2.3.1 应用程序执行环境分层2.3.2 虚拟…

Jenkins流水线初体验(六)

DevOps之安装和配置 Jenkins (一) DevOps 之 CI/CD入门操作 (二) Sonar Qube介绍和安装(三) Harbor镜像仓库介绍&安装 (四) Jenkins容器使用宿主机Docker(五) Jenkins流水线初体验(六) 一、Jenkins流水线任务介绍 之前采用Jenkins的自由风格构建的项目,每个步骤…

链式设计模式——装饰模式和职责链模式

一、装饰模式 1、概述 动态地给一个对象添加一些额外的职责&#xff0c;就增加功能来说&#xff0c;装饰模式比生成子类更为灵活。 ConcreteComponent &#xff1a;是定义了一个具体的对象&#xff0c;可以给这个对象添加一些职责&#xff1b;Decorator &#xff1a;装饰抽象…

JavaEE多线程案例之阻塞队列

上文我们了解了多线程案例中的单例模式&#xff0c;此文我们来探讨多线程案例之阻塞队列吧 1. 阻塞队列是什么&#xff1f; 阻塞队列是⼀种特殊的队列.也遵守"先进先出"的原则. 阻塞队列是⼀种线程安全的数据结构,并且具有以下特性: 当队列满的时候,继续⼊队列就会…

【Linux】VMware 安装 Ubuntu18.04.2

ISO镜像安装步骤 选择语言 English 选择键盘布局 English 选择系统 Ubuntu 虚拟机网卡地址&#xff0c;默认即可 代理地址&#xff0c;默认空即可 镜像地址&#xff0c;修改成阿里云地址 选择第二项&#xff0c;LVM 磁盘扩容技术 第一块硬盘名sda&#xff0c;默认…

Unity游戏实战

很小的时候在键盘机上玩过一个游戏叫寻秦&#xff0c;最近看有大佬把他的安卓版做出来了&#xff0c;打开封面就是Unity&#xff0c;想自己也尝试一下。

R语言的数据结构-向量

【图书推荐】《R语言医学数据分析实践》-CSDN博客 《R语言医学数据分析实践 李丹 宋立桓 蔡伟祺 清华大学出版社9787302673484》【摘要 书评 试读】- 京东图书 (jd.com) R语言编程_夏天又到了的博客-CSDN博客 在R语言中&#xff0c;数据结构是非常关键的部分&#xff0c;它提…

CTF misc 流量分析特训

以下题目来源于西电的靶场&#xff0c;从NewStar CTF开始 wireshark_checkin 进来看一下http流&#xff0c;结果真的找到flag了&#xff08;感觉有点狗运&#xff09;&#xff0c;第一道流量分析题就这么奇奇妙妙的解出来了 wireshark_secret 根据提示猜测flag可能在图片里&…