【Linux进程】环境变量

目录

Linux环境变量

基本概念

常见环境变量

查看环境变量方法

测试PATH

测试HOME

和环境变量相关的命令

环境变量的组织方式

通过代码如何获取环境变量

命令行参数

命令行第三个参数

通过第三方变量environ获取

通过系统调用获取或设置环境变量

​编辑环境变量通常是具有全局属性的

Linux环境变量

基本概念

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

常见环境变量

  • PATH : 指定命令的搜索路径
  • HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
  • SHELL : 当前Shell,它的值通常是/bin/bash。

查看环境变量方法

echo $NAME //NAME:你的环境变量名称

查看环境变量PATH:

测试PATH

下面我们来看一个例子:

1. 我们创建一个myproc.c文件并编译链接成可执行程序,然后对比./myproc执行和执行myproc执行。

我们发现可执行文件myproc加上./就可以进行运行,但是直接运行myproc却会报错。下面我们再来运行一下系统的指令。


2.为什么系统指令如pwd,ls等可以直接执行,不需要带路径,而我们的可执行程序需要带./路径才能执行呢?

其实是因为我们想要执行一个可执行程序,那么我们第一步就必须得找到它在哪里,然后再去执行它。因为系统不知道proc这个文件在哪,加上./是为了帮助系统找到proc这个可执行程序的。

3.那为什么系统指令就不需要带路径呢?

其实系统指令也带了路径了,系统当中Shell会维护一个PATH环境变量,这个环境变量当中带着我们指令的搜索路径。

我们可以看到环境变量PATH中有多条路径,这些路径以冒号作为分隔符隔开,当我们使用pwd或者ls命令的时候,系统就会依次在环境变量PATH的这些路径中进行查找。

我们通过which看到 pwd,cd,ls 都是放在PATH的其中一条路径下面的。

当我们执行的系统命令在这些路径中找到了就会停止查找,然后执行指令。

4. 有没有什么方法让我们的可执行程序可以不用带路径,直接就可以运行呢?

有的将我们的程序所在路径加入环境变量PATH当中。

 export PATH=$PATH:myproc程序所在路径。

对比测试

 从以上运行程序我们可以发现,我们将路径添加到PATH之后就可以运行了。

注意:

修改时这里的指令PATH=$PATH:/....

不能直接使用PATH=/....,这是将path只改成一个路径,发现系统的指令跑不了了。但是这种情况只需要重新登陆即可恢复。

5. 还有什么方法可以不用带路径,直接就可以运行呢?

将你自己生成的可执行程序拷贝到环境变量PATH的某一路径下。

[root@hecs-202562 lesson13]# cp myproc /usr/bin

小结:

1.为什么我们执行指令时不用带路径?shell如何知道我们要执行的指令在哪里呢?

我们新建的可执行程序要运行时往往需要加上./,但系统默认的指令是不需要的如ls,pwd等。因为我们用户登陆时默认就会生成与一个PATH,当我们输入默认的系统指令,会默认到path包含的路径里面找,输入echo $PATH可以打印出其包含的路径,主要每条路径是用:连接的,因此,如果我们想要不输入./就能执行我们新创建的可执行程序,只需要将可执行程序的路径包含在PATH下就可以了,用PATH=$PATH:接新建可执行程序的路径即可。

2.下面我们再来用which看一下我们创建的可执行程序myproc添加到PATH环境变量后能否找到。

 找到了,所以我们更加笃定了Which指令就是根据path环境变量来搜索指令的

PATH=$PATH:/home/GTY/lesson13

测试HOME

我们知道cd~命令可以进入到当前用户的家目录,并且每个用户的家目录是不一样的。

那么操作系统它是怎么知道每个用户的家目录是在哪的呢?

因为每个用户的环境变量HOME是不同的操作系统通过环境变量HOME来保存该用户的家目录

下面我们分别用root和普通用户,分别执行 echo $HOME ,对比差异. 执行 cd ~; pwd ,对应 ~ 和 HOME 的关系

1.root用户执行cd ~; pwd

2.普通用户执行cd ~; pwd: 

 可以看到,root用户的家目录是/root,而普通用户的家目录是/home/普通用户名

这里,~符号代表当前用户的家目录。因此,在root用户和普通用户下,~$HOME是相同的。

和环境变量相关的命令

1. echo: 显示某个环境变量值


2. set: 显示本地定义的shell变量和环境变量

3. env: 显示所有环境变量

4. export: 设置一个新的环境变量


5. unset: 清除环境变量

环境变量的组织方式

 每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串。

通过代码如何获取环境变量

命令行参数

main函数可以带参数吗?

其实我们的main函数是可以带参数,并且它是有三个参数的,因为我们平时基本上都不怎么用他们,所以我们并没有将这三个参数给写出来。

main函数是有这三个参数的:

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

参数说明:

argc:限定命令行字符串个数, 限定只能传多少个参数
argv : 指向一个个的命令行参数
env: 指向一个个环境变量

下面我们先来看一下前俩个参数:

运行结果: 

 默认情况下,命令行参数只有一个,就是我们输入的执行程序命令./myproc

下面我们在命令行多输入几个参数,并用空格隔开。

main函数的第二个参数argv是一个字符指针数组,我们将可执行程序以及它后面的选项都看作是字符串,argv的第一个字符指针存放的是可执行程序后面几个字符指针存放的是可执行程序后面的选项,最后一个字符指针存放的是NULL

argv指针数组存放了argc个指针,当我们输入命令时,系统将我们的命令按空格分割出来,得到argc个字符串,然后把字符串的地址依次放进到argv数组当中

我们知道我们可以通过调用系统指令+不同的选项实现不同的子功能,那么这里我们同样可以通过main函数的几个参数来根据你所给的选项不同,从而打印不同的结果或者实现不同的功能

下面我们来看一段代码:

运行结果: 

 从上面例子可以理解到,为什么我们的系统命令可以带不同的选项。我们调用的是同一个命令,只是调用不同的选项,查看了不同的内容。

 为什么要这么干呢?因为要为指令,工具,软件提供命令行选项的支持!!

命令行第三个参数

运行结果: 

我们发现运行结果其实就是输入env指令打印出来的各个环境变量的值。

通过第三方变量environ获取

运行结果: 

注意:libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时要用extern声明。

通过系统调用获取或设置环境变量

我们还可以通过调用getenv函数来获取环境变量,这也是我们最常用的一种方式。

getenv函数可以根据所给的环境变量名,在环境变量表中进行搜索,从而找到对应的环境变量拿出后面的内容。

下面我们来看一段代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
    printf("%s\n", getenv("PATH"));
    return 0;
}

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

俩张核心向量表!

1.命令行向量表        2.环境变量表

我们一个进程在运行时,不要简单认为我的进程启动就是把程序加载到内存,而是当我们的程序变成进程在启动时,我们一定要有人调main函数,给main函数把这俩张表传进来,一张是命令行参数表,另一张是环境变量表。

上面程序打出来的环境变量和我们的shell打印出来的环境变量是一样的因为我们自己的进程本身是没有环境变量,但当他启动起来,变成进程之后就具有环境变量,因为./运行我们的myproc之后,它会变成进程,而./myproc又是我们的bash的一个子进程。

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

环境变量是系统提供的一组name=value形式的变量,不同的环境变量有不同的用户,通常具有全局属性。

这就是我们上面所说的环境变量具有全局属性,可以让我们的子进程继承下去。

那么如何验证这件事情呢?

首先定义一个本地变量,然后将它export进去( 命令行直接定义的是本地变量,要变成环境变量要将它export一下)

此时我们的系统中的环境变量就新增了MYVALUE这个环境变量

 

 运行结果:

我们的MYVALUE还只是一个本地变量,并不是一个环境变量,它只能够父进程自己去用,所以什么都没有打印。

下面我们让父进程bash通过export指令,将MYVALUE变成环境变量再来看一下吧

 可以看到子进程环境变量也新增了,说明子进程继承了父进程的环境变量

总结:

  • 本地变量, 本地变量指的是我们可以在命令行当中直接定义,但不是定义在环境变量,只会在本BASH内部有效,不会被继承,将本地变量导入环境变量:用export。
  • 环境变量具有全局属性,本质是环境变量可以被子进程继承下去。
  • 环境变量会影响整个"用户系统",影响bash的子进程,逐层往下影响。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值