linux shell环境变量


上一篇文章《什么是linux命令》提到,linux在执行命令之前,其实是经由shell来处理的。Shell等待用户的终端输入,根据用户输入的命令名字, 在环境变量PATH指定的路径下寻找和命令名字匹配的可执行文件,然后创建子进程,该子进程会被linux内核调度执行,在子进程中加载可执行文件并执行。 这就是一条命令执行的一个完整过程。当然这里面涉及的细节,不是一两篇文章可以说的清楚的。后面我会在不同的文章中说明这些细节。shell作为用户和linux内核沟通的桥梁, 可以认为shell是linux内核与用户沟通的默认官方代理人,有很多种不同版本的shell,最常见的是bash shell。所以当我们提到shell的时候,默认就是指的bash shell。 如果你对这个代理人不满意,也可以更换代理人。你甚至可以把python解释器或者perl解释器作为linux的shell。不过几乎没有人会对bash shell不满意,也很少有人这么做。 Bash作为linux的官方默认代理人已是历史约定。这么说只是让大家理解shell,它并没有那么神秘,和其他的脚本解释器,甚至我们敲的命令都是一样的,你可以在shell里再执行shell, 像这样直接敲:bash,就会进入一个新的shell。至于怎么更换默认的shell,这不是这篇文章的内容。以后我会另外一篇文章说明怎么更换默认的shell。
我们回到本文的主题,上面提到shell是去环境变量PATH指定的路径中寻找命令,那么什么是环境变量呢?简单来讲,环境变量是用来设置linux应用程序运行环境的变量。 我们经常接触的环境变量有PATH、HOME、HISTSIZE、HOSTNAME、PS1、PS2等。在shell命令行下可通过“echo $环境变量名”打印环境变量的值, 也可通过env或者export命令查看系统中已有的环境变量。环境变量配置的是应用层的环境,由应用层程序设置并使用。不同的应用程序会关注不同的环境变量。 比如很多时候PATH只会由shell关注,我们经常会配置的java环境变量,会由java虚拟机关注,其他的应用程序是不会关注的。如果你在命令行下只敲了cd,不带路径名, 那么cd就会关注HOME这个环境变量,并切换到HOME环境变量指定的路径中,这个就是登录用户的家目录了。不过cd是shell的内置命令,所以HOME也主要是shell关注的。 我最开始理解环境变量的时候,总是认为它们是内核的一部分,其实环境变量和内核没有多大的关系。环境变量并不是用来配置linux内核的。如果你想对linux内核进行配置, 可以在内核编译配置阶段通过make menuconfig配置或者在内核运行过程中通过sysctl命令配置。
环境变量是用来配置应用程序运行环境的变量,所以环境变量是和应用程序息息相关的,而应用程序在运行阶段是以linux进程的形式存在的,每个进程都有自己的环境变量, 那么这些环境变量存放在哪里呢?他们是从哪里来的呢? 这里我们需要从进程的虚拟地址空间布局着手。每个linux进程(shell也是一个linux进程)都有自己独立的进程虚拟地址空间,进程虚拟地址空间分为内核空间和用户空间, 通常所有的linux进程虚拟地址空间的内核空间896M以内的空间会直接线性映射到物理内存的0-896M空间内。为什么是896M,这也是历史条件下形成的。 剩下的虚拟地址空间内核会按照自己的分页机制,间接的映射到物理内存中。关于这部分内容就是linux内核的内存管理部分了,本文不作深入讨论。 后面会专门抽出时间写一篇内存管理的文章。
说的环境变量,为什么会扯到进程虚拟地址空间呢?因为我们的环境变量是以环境变量表(数组)的形式存放在进程虚拟地址空间的用户空间里。这也是我上面说环境变量和内核没什么关系的原因。 进程虚拟地址空间的布局图如下图所示:
Linux内核在内存中的布局 进程虚拟空间布局 这张进程虚拟内存布局图是本人所画的《linux内核原理大图》的局部。该图目前还在创作中,已完成大部分。关注本头条号,可随时关注本人最新文章。 图中深红色的gap上方为内核空间,gap下方为用户空间。内核空间和用户空间有gap隔开。这也是内核的一种保护机制。这张内存布局图非常重要, 在linux下学习c/c++编程的人应该对这张图比较熟悉,因为不管是c/c++还是linux内核,原理性的东西都是围绕着这张图展开的。这张图毫不夸张的说, 就是打开linux环境下c/c++基础编程的金钥匙。
在用户空间的最上部,stack和gap中间,就是环境变量表所存放的位置了。我们的进程如果要想获取环境变量或者设置环境变量,都是从这个内存区域获取和设置的。 该部分会通过内核分页机制映射到物理内存中。
那么这里的环境变量又是从哪里来的呢?在《什么是linux命令》一文中,我们指出,linux运行一条命令,就会创建出一个进程,而这个进程是由shell创建的。 也就是你在linux下执行的任何命令所创建的进程,都是shell的子进程。所以一个进程的环境变量,大部分都是从shell进程继承而来的。 子又生孙,孙又生子,子子孙孙无穷尽也,而山不在高...
不好意思,我学的有点杂,我们回到主题。那么shell进程的环境变量又是从哪里来的呢? 我们前面说过,shell作为linux内核与用户打交道的代理人,所以要面对各型各色的人, 每个人都有不同的喜好。我们上文提到,可能会有人在小角落里密谋想要替换掉bash shell,Shell为了留住大家的心,适应不同人的喜好,就允许每个用户设置自己的环境变量。所以shell的环境变量其实就是用户你(你是主角,出场要带特效)自己设置的。 所以我们经常说环境变量的时候,前面总是加上shell,叫shell环境变量。每次shell启动的时候,都会读取一系列的环境配置文件。 将环境配置文件中环境变量的值读到自己内存空间的位置, 也就是上图所说的位置啦。然后由shell生成的子进程就会继承shell的环境变量。那么shell(我们这里主要说的bash)的环境变量配置文件存放在哪里呢? 有哪些设置环境变量的方法呢?我知道如果文章写的太长,就没有人会有耐心看下去的,所以我会在下一篇文章中说明shell环境变量的配置。因为平时还要养家糊口, 我的出文速度有点慢,所以机智的你,在还没等到我的文章之前,就已经找到答案了。那么这篇文章也算起到抛砖引玉的作用了。
我们在知道一样东西的来龙去脉后,是不是学习起来就更加顺手了呢。当然还是那句话,你知道的越多,不知道的也越多。这边文章又挖了很多坑, 欢迎关注本头条号,我们一起挖坑,一起填坑。本人水平有限,如果文章有误,欢迎批评指正。

相关阅读:
linux基础
linux怎么学
计算机启动过程详解
磁盘构造和磁盘分区
什么是linux shell
什么是linux shell环境变量
linux shell环境配置文件解析
initroot编辑整理,转载请注明www.initroot.com

100次点赞 100次阅读