目录
一、什么是环境变量:
1、系统命令搜索路径(PATH):
2、HOME:
3、SHELL:
4、添加环境变量:
二、通过代码获取环境变量:
三、主函数参数:
argc表:
envp表:
内建命令:
一、什么是环境变量:
Windows下的环境变量查看:
环境变量是指在操作系统中用来指定操作系统运行环境的一些参数,环境变量是系统提供的name=value的变量,不同环境变量有不同的用途,通常具有全局属性。在Linux中,可以使用env(实际上是environment的简写)指令来进行当前环境变量的查看:
接下来介绍几个重要的:
1、系统命令搜索路径(PATH):
我们前面说过我们执行的指令事实上也是一个个写好的程序,但是为什么执行指令的时候不需要带路径,而执行自己的程序的时候就必须要带路径呢,这是因为当执行一个程序的时候,会先在PATH里面的路径下查看该程序是否在这些路径下,每个路径之间用冒号分割开,用指令:echo $PATH可以查看该环境下的路径
如果在PATH中就不需要在执行程序前面加上路径,比如我们的指令:
我们的指令的路径/usr/bin/就在PATH后面找得到就不需要加路径
但是像我们自己写的程序就在PATH中找不到,这个时候就需要带上路径,如果不带上就会有not found ,证明bash它在PATH中找了但是找不到
那么如何增加PATH中的路径呢?
如下:PATH=$PATH:你要加的路径,(注意,这里要加$PATH: 如果不加就会全部覆盖掉,也很好理解$PATH:就是把之前的写上去用冒号分割开,再在后面加上新的路径)
然后就加好了,加好后在新的路径下的程序也就可以不用带路径了,因为这里的环境变量是内存级的,所以重新登录一下就会变成默认的PATH
如果一不小心给PATH全部覆盖了也不要紧,重新登录一下shell就会变成默认的PATH
2、HOME:
指定用户的主工作目录,即用户登录到Linux系统中的默认所处目录,也是只执行cd指令后跳转的目录
3、SHELL:
查看当前是哪种命令行解释器,我们所执行的各种命令都是由命令行解释器进行解释的,如下,我这的是bash
接下来就简单讲下剩余的环境:
如上:
HISTSIZE:这个是bash帮我们记录的前1000行指令
PWD:这个就是当前所处路径
LOGNAME:表示当前用户的登录名。用于存储用户登录系统的用户名信息。在大多数情况下,LOGNAME的值与当前登录的用户名相同
上面这个很长的是ls的配色方案
这个是表示当前SSH会话的终端设备文件路径。当用户通过SSH连接到远程服务器时,SSH客户端会为该连接创建一个虚拟终端设备,SSH_TTY环境变量就记录了这个虚拟终端设备的路径,
如下:在一个bash中就可以像下左的方式进行像右边的bash中输入
4、添加环境变量:
环境变量与本地变量
本地变量,在命令行中正常定义的变量就是本地变量,如下的inta,在环境变量里是看不到的
如果想变成环境变量就需要通过export导入到环境变量中:
这样,inta就能够被子进程共享,如果想在环境变量中删除就使用unset 环境变量名
环境变量具有全局属性,能够被所有子进程共享,本地变量不会被继承, 只会在bash中被使用
二、通过代码获取环境变量:
getenv()函数:
在如上函数就在stdlib.h的库函数中,在代码中的使用:
#include<stdio.h>
#include<stdlib.h>int main()
{char* arr = getenv("PATH");printf("PATH:%s\n",arr);return 0;
}
编译后就进行运行就可以直接打印出对应的环境变量
这个就可以自己基于环境变量PWD实现pwd这个指令:
#include<stdio.h>
#include<stdlib.h>int main()
{char* pwd= getenv("PWD");printf("%s\n",pwd);return 0;
}
这样运行程序就是直接打印当前目录,再根据之前学过的:将这个程序放到PATH环境中对应的路径下面,就可以实现pwd指令了
还有判断root账号的做任何事也是可以基于环境变量中的USER进行判断的
三、主函数参数:
在Linux中:对于main函数来说,它的括号里面是可以带参数的,其中可以带三个参数:
1、int argc:这个就是传入程序中的元素个数,一共有几个字符串就初始化argc为几
2、char* argv[]这是一个指针数组,这个指针数组的个数就是argc个
3、char* envp[]环境变量表,环境变量全局性就是指main函数可以通过此参数获取到环境变量表的信息
4、上述的两个表的最后一个都是NULL,所以在判断的时候可以直接argv[i]即可
argc表:
这个存储就是把命令行字符串以空格分开,然后依次将argv里面的指针指向对应的字符,这样就可以实现那些命令行字符后面的选项了,本质上是同一个指令,根据不同的选项进而执行不同的功能
这样在运行的时候就可以在后面带选项了
这样就可以根据选项实现不同的功能了:
这样就能够实现类似于我们之前的指令加选项例如:ls -a,ls -l等等
envp表:
envp也是类似于kv结构的,这样也可以用打印argv的方式打印这张表看看:
如下打印出来的这张表和我们env指令出来的环境变量是一模一样的
事实上:进程在运行的时候,不要认为就是将程序加载到内存,而是当程序变成进程在启动的时候,一定要有人调用main函数,给main函数把这两张表传进来,一张叫做命令行参数表(argc),一张叫做环境变量表(envp)
environ变量是一个char**类型的变量,其中存放着系统的全局变量,可以通过对environ输出来输出系统的全局变量,因为environ是一个外部的全局变量,所以在使用时需要用extern声明一下
可通过如下代码来拿到环境变量的数据,这样就不需要main函数中的参数了
内建命令:
命令有两批命令:
常规命令:通过创建子进程完成的,比如pwd,ls
内建命令:bash不创建子进程,而是由自己亲自执行,类似于bash调用自己的函数或者是系统提供的函数,如echo,cd
所以有结论:bash里面的指令并不都是bash的子进程
我们实现内建命令cd来理解内建命令:
这里需要使用unistd.h文件下的chdir函数,进行操作,chdir函数就是修改目录,int chdir(const char *path),这里的path可以是绝对目录或者相对目录,然后功能就是改变当前的工作目录,修改为path
如上所示:通过传过来的第二个参数作为新路径,然后直接用chdir(argv[1])来拿到这个新路径更改这里的sleep是为了方便观察
如上所示,这就是首先程序启动后,观察该进程的pid,然后找到该进程所在的路径,这里是/home/silence/ZT,接着改到根目录下,这样的话过30秒后进行查看,就可以看到目录被修改了