【解锁创意之门:环境变量引领你的编程奇思妙想】(上):https://developer.aliyun.com/article/1425748
当i++后,此时argv[i]就访问到了NULL,NULL对应的就是0,此时程序就会退出。通过上面我们知道main函数的两个参数是从命令行输入的,然后再由bash创建、维护并传参的,可是我们为什么要这么做呢???下面我们来写一个demo,来说明我们为什么要这么做。demo的功能是输入./myprocess -[number](1-3)可以实现不同的功能,只能传入两个参数。
我们来看一下程序的运行结果:
通过上面的demo,我们发现我们可以通过不同的选项,让我们的同一个程序执行它内部不同的功能!为什么呢?我们看一下下面这张图片。
我们发现我们平时使用的指令,后面跟着的都是我们的指令选项,这不就是和我们上面demo一样嘛,这些指令大部分也都是使用c语言去写的,选项的本质也就是命令行参数,所以我们平时使用的选项,最终都是以命令行参数的形式传递给我们main函数,然后我们可以根据选项去实现不同的指令功能。命令行参数,是Linux指令选项的基础!
3.2.环境变量 --- 初步并了解并使用环境变量
我们先来见见环境变量,我们运行我们的程序要运行就需要./myprocess或者找到这个可执行程序的绝对路径运行这个可执行程序,如果我们不以上面的两个方式,此时就会出现command not found的错误信息,这句话的潜在意思就是我们系统在执行myprocess的时候,系统没有找到这个可执行程序。
这里有一个问题,为什么执行我们的程序要./,而执行系统自带的指令就不用呢?比如ls,没见到我们用./ls呀!这是因为系统存在一个全局的环境变量PATH,我们可以通过echo $PATH打印出这个环境变量里面的内容。
所以上面的问题就能解决了,因为ls的执行路径默认就在/usr/bin/这个路径下,所以ls指令执行的时候就可以找到执行路径,而myprocess的路径是/home/whb/110/110/lesson12,没有被添加到环境变量PATH里,所以我们输入myprocess找不到执行路径,也就会给我们输出command not found的错误信息。PATH环境变量里面保存的是我们Lixnu系统搜索可执行程序时所对应的搜索路径。如果我们要想我们自己的程序也和ls一样直接执行,我们由两种方法:
1.将我们的mprocess拷贝到/usr/bin/这个路径下:
2.把自己的可执行程序添加到环境变量PATH里
此时我们再通过which就可以查到我们自己的可执行程序了
如果我们把之前的环境变量给覆盖了怎么办?很明显此时就只能我们自己的程序能够运行,系统提供的那些指令都不能使用了。
那怎么办?所有的基本的指令都不能使用了。不用担心此时,我们现在修改的环境变量它仅仅是在内存当中,由系统开辟的内存级的变量,此时我们重新打开Linux系统即可。我们再来看一下环境变量,当我们执行pwd的时候,它是怎么知道我们当前所处的路径的呢?是因为我们系统存在一个PWD的环境变量:
这个环境变量会时时刻刻观察当前用户的路径的变化,当用户切换了路径,PWD的环境变量也会相应的做出变化,进行同步更新。
我们再来看一下环境变量,当我们执行whoami的时候,它是怎么知道我们当前用户呢?是因为我们系统存在一个USER的环境变量:
当用户登录系统的时候,USER的环境变量会记录首次登录的用户是谁,然后将用户名记录在USER的环境变量中。还有其他环境变量我就不一一介绍了,我们可以通过env查看系统中已经存在的环境变量。
那这里我们就可以粗略的理解一下环境变量,环境变量是由bash提前在给每一个人在登录的时候,提前在内存里面开辟一块空间,开辟好之后,把这个人的基本信息写入到这块空间里,所以这个用户在使用Linux系统的过程中,系统直接可以通过环境变量认识用户,就好比入职公司之前,公司会提前把我们的工牌做好,此时领导或者公司同事就可以通过工牌认识你。所以预先给用户准备的一批变量就是我们的环境变量,也就是我们进入了Linux这个系统环境而提前准备的变量。
常见环境变量
- PATH : 指定命令的搜索路径
- HOME : 指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)
- SHELL : 当前Shell,它的值通常是/bin/bash。
3.3.环境变量 --- 特性 --- 命令行参数
和环境变量相关的命令
- 1. echo: 显示某个环境变量值
- 2. export: 设置一个新的环境变量
- 3. env: 显示所有环境变量
- 4. unset: 清除环境变量
- 5. set: 显示本地定义的shell变量和环境变量
查看环境变量方法:
echo $NAME //NAME:你的环境变量名称
那我们想要自己定义一个环境变量呢?export: 设置一个新的环境变量
上面我们知道main函数有两个参数,实际上main函数还有一个参数char* env[];这个env和我们的argv一样,env也是一个数组指针,内部每个指针指向的就是环境变量。
环境变量的组织方式:
每个程序都会收到一张环境表,环境表是一个字符指针数组,每个指针指向一个以’\0’结尾的环境字符串。
运行结果:
此时我们就会发现系统会把环境变量以main函数的参数的形式传递给我们的进程.myprocess。然后我们再来改一下我们的代码。
运行结果:
通过上面的结论我们可以知道环境变量是默认是可以被子进程继承的,那我们的孙子进程呢?我们再来修改一下我们的代码。
这里的运行结果也显示了孙子进程,它也被我们的孙子进程所继承。因为我们创建子进程的时候,这个环境变量的数据本来也应该属于子进程,因为创建子进程的时候代码共享,数据以写时拷贝的方式各自私有一份。所以环境变量具有全局属性,环境变量会被所有的子进程包括孙子进程进行继承!!!也就意味着我们在bash命令行添加的任何环境变量,将来在我们的子进程都可以看到。
环境变量基本概念
- 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数
- 如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。
- 环境变量通常具有某些特殊用途,还有在系统当中通常具有全局特性
3.4.环境变量 --- 代码获取和设置环境变量
除了上面的命令行第三个参数获得所有环境变量,我们还可以通过函数getenv去获得一个环境变量。
#include <stdio.h> #include <stdlib.h> int main() { const char* username = getenv("USER"); if(username) printf("username:%s\n", username); return 0; }
运行结果:
此时我们就获得了环境变量。那么环境变量到底有什么用呢?
运行结果:
此时系统通过环境变量USER知道当前用户是whb,就让该用户运行核心的代码,当我们有另外一个用户root登录的时候,操作系统此时就会形成该用户的环境变量,USER就是root。然后以root的身份去执行代码,此时就没有权限了。
此时我们就可以通过不同的用户根据自己的环境变量执行自己相应的代码。比如通过环境变量做一些身份识别的功能 - 比如优酷的普通用户和VIP用户。除了通过上面的命令行第三个参数获取环境变量,还可以通过第三方变量environ获取。我们可以先来看看eviron是什么,我们可以通过手册查看:man eviron
现在我们来写一个代码来验证一下
#include <stdio.h> #include <unistd.h> int main() { extern char** environ; int i = 0; for(;environ[i];++i) { printf("environ[%d]:%s\n",i,environ[i]); } return 0; }
第三方变量environ是一个二级指针,它在这里也指向一个char*的数组。
注意:libc中定义的全局变量environ指向环境变量表,environ没有包含在任何头文件中,所以在使用时要用extern声明,我们只能对它进行声明,不能进行定义。我们上面有一个结论:环境变量具有全局属性,那么现在我们在bash进程导入一个环境变量:export myenv=aaaaaaaaaaaaaaaaaaaaaa;当我们再次运行上面的程序时,此时这个程序是在bash运行的,那么父进程也就是bash,而我们上面的程序就是bash的子进程,同时子进程也会继承父进程的环境变量,所以当我们运行之后,我们也可以在子进程中看到刚刚设置的环境变量了。
除了环境变量,程序中还可以使用本地变量,我们来看一下
通过上面的图片我们可以知道设置本地变量不用加export,同时我们无法通过env查到本地变量,那我们该怎么查询本地变量呢?我们可以使用set查看,set会把bash所有的变量全部展示出来,包括环境变量和本地变量。
我们可以通过getenv获取一个变量。
运行结果:
如果我们获取本地变量呢?const char* myenv=getenv("hello");
我们在bash命令行输入echo $hello可以看到本地变量hello,但是当运行上面的程序就无法看到。所以我们就可以得出一个结论:本地变量只在bash内部有效,不能被子进程继承下去,即本地变量不是环境变量,本地变量只在bash内部有效。
设置变量有了,那怎么移除变量呢?使用unset + 变量名
【解锁创意之门:环境变量引领你的编程奇思妙想】(下):https://developer.aliyun.com/article/1425758