🚀每日鸡汤:
智者重因,庸者重果,顺道而行。
目录
一、基本概念
🖊环境变量一般是指在操作系统中用来指定操作系统运行环境的一些参数。如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。其实,说白了环境变量就是全局设置好的变量,方便我们后续程序的执行。
🖊环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性。
在Windows下我们是有环境变量的:
那么Linux下,我们的环境变量又是什么形式呢?
Linux下的常见的环境变量有:
🖊PATH: 指定命令的搜索路径
🖊HOME:指定用户的主工作目录(即用户登录到Linux系统中时默认的目录)
🖊SHELL:当前Shell,它的值通常是/bin/bash
查看环境变量的方法: echo $NAME //NAME:你的环境变量名称
ⅠPATH
可能还是有点抽象,在Linux下我举个例子,比如我们要执行一个程序(指令),要先找到这个程序,比如./myprocess --> ./当前路径 ->找到程序。需要./可执行程序。而Linux下其实一个一个指令就是一个一个可执行程序,那么系统在执行指令的时候为什么不需要加./ 呢?这是因为系统配备了全局环境变量,它会默认去自动去查找。
那我也不想加./怎么办呢?有两种办法:
①把我们的可执行程序拷贝到系统 /usr/bin/中
/usr/bin/是系统安装指令的路径
但是不敢这么做,因为我们写的没有经过测试,会污染系统指令词。
②配置环境变量
🖊PATH: 指定命令的搜索路径。
我们通过echo $...
可以查看环境变量PATH
这些是什么意思呢?冒号分割的这些都是目录,这些目录就是系统配备的,系统在执行指令会默认到冒号间隔的每一个目录下去检索搜索指令,存在的话就找到执行。
系统指令能执行,是因为指令都在/usr/bin/目录下。
既然如此我们只要把我们的路径添加到这些环境里面就可以了。我们需要用到export指令。
错误使用:
这种做法会覆盖环境变量。
正确使用:
export PATH=$PATH 先把我们的环境变量导入, 冒号:用于 分割 要添加的路径:/home/Gyh/lesson10,此时就添加进了。
当然,我们可以查看Linux下的系统环境变量还有哪些:
那么在Windows下
这些比较多,而且我们看不懂,我们来看一下系统提供的一些需要我们管着环境变量:
HISTSIZE表示我们最多能查看的历史命令条数,我们能通过history指令再来具体查看我们历史使用了哪些指令:
env能查看当前目录下的环境变量:
Ⅱ getenv函数
我们之前了解到echo $环境变量可以在命令行查看环境变量,那么我们在程序中如果想查看环境变量是如何做到呢?这里提供了一个getenv函数来查看环境变量。
我们通过man手册来查看这个函数:
//头文件
#include<stdlib.h>
char* getenv(const char* name);
//返回值 char*
//参数:已经存在的环境变量名称
对于已经存在的环境变量,我们输入字符串名称便可以查询其内容:
Ⅱ user环境变量
user环境变量,用于查询当前使用用户。我们可以通过getenv函数来查看这个环境变量。
这里我们看到,我们在不同用户下user环境变量是不同的。也就是说user可以识别当前用户。
这里我们也就知道了当我们打开一些文件为什么会提示我们权限不够,就是它配置user环境变量对当前用户身份识别。
其实,sudo的本质就是把user这个环境变量由普通用户改为root。
Ⅲ PWD环境变量
PWD环境变量是查看当前路径的环境变量。
这个命令非常简单,我们可以自己写一个添加到环境变量。
当然,别忘了删除哦!
二、shell变量(本地变量)和环境变量
首先我们先介绍一些与本地和环境变量相关的命令,然后具体实操它们之间的联系和区别。
🖊echo $变量名:显示某个环境/本地变量值
🖊export:设置一个新的环境变量
🖊env:显示所有环境变量
🖊unset:清除环境/本地变量
🖊set:显示本地定义的shell变量和环境变量
本地变量和环境变量有什么区别呢?我们来看以下的操作:
本地变量就是命令行定义的shell变量:
那么我们env查看环境变量:
在这里我们只查看到shell定义的变量没有export是不会被添加到环境变量的。当我们添加后,我们在程序中能用getenv函数查看吗?
我们发现,我们添加后的环境变量是可以在程序中调用查看的。
如果我们没有把shell变量添加到环境变量在程序中调用函数是查看不到的。
那么说了这么多,shell本地变量 和环境变量表面上区别就是能不能被程序调用,有啥用呢?
我们知道bash是一个系统进程,这里我们创建的可执行程序myecho、addenv是bash的子进程。也就是说环境变量具有全局属性能被子进程继承下去!!环境变量是设置给bash的,子进程会继承这些变量。而shell本地变量--没有添加到环境变量,没有export,只会在当前进程(bash)内有效,不能被继承!
既然env不能查看环境变量,那么用什么指令来查看shell本地变量呢?
set指令!
set命令可以查看本地变量,那么我想取消一个shell本地/环境变量,使用unset指令。
三、命令行参数
Ⅰargc&&argv
不知道有的老铁是否知道main函数也是有参数的呢?
int main(int argc,char* argv[])
{}
这里的argc和argv参数是什么含义呢?通过类型我们知道argc是一个整数,而argv表示指针数组,我们可以把它打印出来看一下:
我们看到当我在命令行内容不断变多时,打印的内容也在随之增加。我们可以类比ls指令。
我们这里的命令行参数本质就是把程序名和选项依次传给argv指针数组,而argc表示程序名和选项加起来有几个,argc值就是多少,argv数组就有多大。具体系统在这里是如何操作呢?我们举个例子:
长字符串以空格位间隔拆成一个一个子字符串。argv指针数组存这些字符串,默认情况下指针数组第一个argv[0]就是输入的第一个字符串"ls"
所以命令行参数的意义就在于命令行选项控制:
同一个命令打印出来的东西不一样,是通过它的选项控制的!
这里还要提一嘴gcc编译器编译问题,有的老铁可能写for循环编译不过去:
这是因为gcc编译器版本过低,需要添加c99标准:
Ⅱenv参数
完整的main函数参数应该有三个:
int main(int argc,char* argv[],char* env[])
{}
这第三个参数就是环境变量。
后面就是我们的环境变量以字符串打印出来的内容,我们可以自己添加一个环境变量执行验证一下。
四、三种查看环境变量的方法
其实这里我们正常写程序不需要写main函数的参数,那么我们想查看所有环境变量如何查看呢?
之前我们已经提到getenv函数可以查看某个已经存在的环境变量,系统还提供了一个函数environ,我们通过man手册查看一下:
我们可以看到,它是一个二级指针,对它解引用得到
其实对他解引用就能得到env的每一个成员,也就是环境变量。
我们可以具体写一个程序来查看一下:
至此,这里可以总结一下程序中获取环境变量的三种方式:
🖊1、getenv()函数
🖊2、main参数 char*env[]
🖊3、extern char** environ--environ函数
其实是由四种方式,还有一种是evho $环境变量 ,这不过这是在命令行查看环境变量,这里所说的三种方式是通过程序查看环境变量的方式。
推荐使用getenv()函数,可以根据环境变量名字直接拿到内容,而其余两种方式是把所有环境变量列举出来查看,有很多不需要关注的内容,没必要列举。
这里遗留一个问题:echo是一个子进程吗?如果老铁觉得是,那么为什么它可以打印本地变量呢?
因为我们知道本地变量不能被子进程继承,而这里的ddt是一个本地变量啊。why??
echo不是子进程!!这里可以简单解释一下:
echo命令在父shell中执行,echo通过管道将内容输出到子进程中,管道可以用于父子进程之间通信,因此子进程可以拿到父进程输出的内容,这里涉及到进程间通信的内容,且听下回分解❤。