目录

一、什么是环境变量:

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秒后进行查看,就可以看到目录被修改了

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部