朋友们、伙计们,我们又见面了,本期来给大家解读一下有关Linux环境变量的相关知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成!
C 语 言 专 栏:C语言:从入门到精通
数据结构专栏:数据结构
个 人 主 页 :stackY、
C + + 专 栏 :C++
Linux 专 栏 :Linux
目录
1. 环境变量
1.1 基本概念
1.2 常见的环境变量
1.2.1 PATH
1.2.2 PWD
1.2.3 HOME
1.2.4 查看全部环境变量
2. 获取环境变量
2.1 getenv接口
2.2 mian函数的第三个参数
2.3 定义并导出环境变量
2.3.1 内存级别
2.3.2 更改环境变量脚本配置文件
2.4 通过第三方变量environ获取
3. 本地变量和环境变量
4. 与环境变量相关的指令
1. 环境变量
一个可执行程序要能运行起来或者是一个指令要能跑起来,首先得找到这个可执行程序,我们在启动我们的可执行程序的时候,前面都要加上一个 ./ 在当前路径下查找这个可执行程序,我们在命令行中输入的指令它本质上也是可执行程序,那么为什么它不需要查找呢?
我们使用的指令也是经过查找的,只不过不需要我们自己手动查找,会存在默认的搜索路径,这些路径参数就是OS内部的环境变量。
1.1 基本概念
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
1.2 常见的环境变量
查看环境变量的指令:echo $NAME //NAME:环境变量名称
1.2.1 PATH
PATH : 指定命令的搜索路径
首先就是我们指令的默认搜索路径的环境变量:使用 echo $PATH 指令查看
- 以 : 为分割符,分割的这些字串就是一个个的搜索路径;
- 在执行我们的普通指令的时就会默认在这些路径下按照顺序搜索;
那么我们能否将我们的可执行程序的路径也添加进去呢?
答案是可以的,只需要使用PATH=$PATH:路径(中间不能有空格)
同样的,将我们的可执行程序直接拷贝到这些搜索路径中,也是可以直接执行的,这种方法就叫做程序安装。
默认更改的环境变量是内存级别的(只限于本次登录)重新登录之后就会恢复默认。
1.2.2 PWD
PWD:记录当前位于哪个目录下
在命令行中我们使用的pwd命令他是怎么知道我们当前位于哪个路径下的?
肯定是在这个指令中封装了查看PWD环境变量的一些调用,然后将该结果返回给我们。
1.2.3 HOME
HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
在Linux中分为普通用户和超级用户,那么当普通用户刚刚登录进去时它所处的路径在/home/XXX下,超级用户在登录进去时在/root下,那么为什么两个用户的所在路径不一样呢?又是怎么做到的呢?
使用echo $HOME 查看该环境变量:
该环境变量刚好记录的就是普通用户和超级用户的主工作目录。
所以在我们登录的时候:
1. 输入用户名和密码
2. 认证
3. 形成环境变量(PATH、PWD、HOME......)
3.1 根据用户名来初始化HOME=/root ro HOME=/home/XXX
4. cd $HOME
1.2.4 查看全部环境变量
env指令:查看所有的环境变量
在系统中会存在大量的环境变量,每一个环境变量都有都有它特殊的用途,用来完成指定的系统功能!
2. 获取环境变量
获取环境变量一共有三种方法,接下来就一次介绍:
2.1 getenv接口
系统调用接口:getenv
传递所要获取的环境变量的名称,它的返回值就是环境变量的内容。
我们可以使用系统调用配合环境变量来指定的执行一些代码:比如只能让超级用户具有执行代码的权利:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char* name = getenv("USER"); if(strcmp(name, "root") != 0) { printf("这是一个非法用户:%s\n", name); return 1; } printf("myself command!\n"); printf("myself command!\n"); printf("myself command!\n"); printf("myself command!\n"); return 0; }
2.2 mian函数的第三个参数
在上一章节的命令行参数中,说到main函数可以带两个参数,第一个参数是命令行输入的选项个数,第二个参数是该选项被分割的字串,那么在本章节,就要介绍main函数的第三个参数:
int main(int argc, char *argv[], char *env[]) {}
该参数是一个字符指针数组,里面保存的是字符串的地址。
当我们在命令行中使用env指令时会给我们打印出来所有的环境变量信息,那么这个信息是从哪里来的呢?
在Linux登录时会创建一张环境变量表,这张表的名字就叫做char *env[],这张表中每个下标位置都对应的是一个kv结构的环境变量,最终以NULL结尾。
系统启动时,可以给我们的进程(mian)提供两张表:
1. 命令行参数表
2. 环境变量表
可以使用main函数的第三个参数来查看环境变量
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/types.h> #include <unistd.h> int main(int argc, char *argv[], char *env[]) { for(int i = 0; env[i]; i++) { printf("pid: %d, env[%d]: %s\n", getpid(), i, env[i]); } return 0; }
并且打印出来的环境变量信息和命令行使用env指令的信息一样。
我们在命令行中./启动的进程都是shell/bash的子进程,所以子进程的命令行参数和环境变量是父进程传递的!
那么父进程的环境变量信息又从哪里来?
当我们更改环境变量时,不小心改错了,那么没关系,只需要重新登录就可以恢复原来的环境变量,所以说我们更改环境变量信息默认更改的是bash进程内部的环境变量信息!每一次重新登录都会形成新的bash解释器,并且新的bash解释器会从指定位置中读取自己的环境变量表信息!
环境变量信息是以脚本配置文件的形式存在的,这个配置文件在家目录下的.bash_profile文件:
所以在每一次登录的时候,bash都回读取.bash_profile配置文件中的内容为bash形成一张环境变量表信息,那么bash拿到了环境变量信息,就可以将环境变量信息传递给它的所有子进程。
2.3 定义并导出环境变量
2.3.1 内存级别
在我们的命令行中可以直接定义一个环境变量:
MYENV_TEST1=helloLinux
MYENV_TEST2=helloWorld
然后使用export命令导出环境变量:
export MYENV_TEST1
export MYENV_TEST2
也可以直接定义+导出:
export MYENV_TEST1=helloLinux
export MYENV_TEST2=helloWorld
这样的配置是内存级别的,重新登录就不见了。
2.3.2 更改环境变量脚本配置文件
直接在.bash_profile配置文件中添加环境变量
这样就做到了每次登录就会自动读取配置文件中的环境变量信息。
如果我们导出了一个环境变量, 那么这个环境变量信息可以被它的子进程全部读到的,所以我们说系统环境变量具有全局属性!
2.4 通过第三方变量environ获取
#include <stdio.h> int main() { extern char **environ; //第三方变量 int i = 0; for (; environ[i]; i++) { printf("%s\n", environ[i]); } return 0; }
3. 本地变量和环境变量
在Linux的命令行中,我们可以直接定义本地变量:
可以看到定义本地变量时跟定义环境变量一样,只不过定义环境变量时需要使用export进行导出。
那么本地变量和环境变量有什么区别呢?
本地变量只在bash进程内部有效,不会被子进程继承下去。
环境变量通过让所有的子进程继承的方式,实现自身的全局性。
我们都知道,在命令行中执行的命令也是一个子进程呀,那为什使用echo指令时还能看到bash定义的本地变量呢?
Linux中的指令分为两类:
1. 常规命令:shell通过fork之后让子进程执行的命令。
2. 内建命令:shell命令行的一个函数,使用时相当于函数调用。
echo命令就属于内建命令,所以可以看到bash定义的本地变量。
4. 与环境变量相关的指令
1. echo: 显示某个环境变量值2. export: 设置一个新的环境变量3. env: 显示所有环境变量4. unset: 清除环境变量5. set: 显示本地定义的shell变量和环境变量