Linux - 环境变量 - 常规命令 和 内建命令

news2024/11/27 10:32:28

推荐书籍,《深入理解Linux内核》。鸠摩搜书 | 全网电子书搜索引擎,小说人必备 | Tbox导航 (tboxn.com)


寄存器

你应该知道,代码是被加载到内存当中,cpu才能进行运算的,那么,我们在写函数返回值的时候,或者是这个程序的返回值我们是怎么拿到的呢?

其实很简单,就是靠 cpu 当中寄存器。cpu 当中寄存器有很多个,根据使用的编译器不同,各种方式功能,使用的 寄存器都有所区别。

当函数要返回一个值之时,会先用move 指令把这个函数的返回值存储到一个寄存器当中(其中的 eax 就是一种寄存器,当然这里只是举例子,不同编译器可能使用不同的 寄存器):

return -> mov eax 10

然后,如果在函数外部有 对应变量来接收函数的返回值的话,就会 再次使用 move 指令把寄存器当中的数据,拷贝到 对应变量当中:
 

int a = add(a,b);
mov eax -> a

所以,当你的 函数返回值 的数据很多时,比如返回的是一个非常大的结构体对象,那么我们一般是不使用 传值返回,因为传值返回就会占用多个寄存器,因为寄存器的大小不大。我们一般是在堆上开辟空间,因为堆上的空间不会随着函数栈帧 的销毁(栈的销毁)而销毁,在返回只是也不是返回 一个堆上的空间大小,而是直接返回这个堆空间的首地址。 


系统如何得知,当前进程运行到哪一行代码的?

cpu 还使用 寄存器来记录当前执行到代码的那一行了。

 在cpu 当中有一个寄存器,叫做 程序计数器。在很多教材当中 喜欢把它叫做 PC指针,eip。说白了这个就是一个计数器,记录当前进程正在执行的指令的下一行指令的地址

比如,当前cpu正在执行的是 50 行代码,那么 程序计数器 记录的就是 第 51 行地址。 

 所以,我们在写高级语言时,会遇到顺序语句,逻辑语句,循环语句。也就是程序计数器在计算下一行要执行的语句的行数 的 算法不同而已。

例如顺序语句就是顺序往下依次递增;循环语句就是,在循环体当中按照 各行代码 语句执行,当执行到 循环体最后一行,重复循环体第一行进行执行。


cpu 当中的寄存器有很多,比如:

  • 通用寄存器:eax,ebx,ecx,edx····· 这种寄存器只要 有人想用,就能用。
  • 栈帧:ebp,esp,eip
  • 状态寄存器:staus···· 可以用于 实现 进程 调度算法。
  • ··························

 那么寄存器扮演者什么角色呢?

首先,寄存器也具有,对数据进行临时保存的能力。计算机在运行时,一些重要的数据,必须保存到cpu 当中。因为 放在 cpu 内部,这些数据才会离 cpu 更近,而且,寄存器取放数据的效率高。

所以,cpu 为了提高效率,就会把 处理频率高的数据(进程的高频数据),放到寄存器当中。也就是说,cpu 内的寄存器,存储的是进程相关的数据,这部分数据是会随时被cpu 访问和修改的。

而且,这部分数据都是进程的临时数据 -- 进程的上下文

 当某一个进程的要离开之时,要把自己的进程上下文数据保存好,甚至带走。保存带走的目的就是为了,当这个进程在进程切换回到cpu当中执行之时,进程可以恢复到之前的运行状态,也就是上次运行是运行到哪一步了。让 cpu 知道加下来该如何运行这个进程。(这个过程被称之为 -- 保存进程上下文的操作

如果只是把进程的临时数据都在cpu 当中保存的话,当新进程想进入的时候,只是简单粗暴的把进程的数据和代码拷贝到 cpu 当中,那么,cpu 当中 老进程的数据不就被覆盖了吗?

所以,进程再被切换的时候,会做两件事情(这个过程称之为进程切换的操作):

  1. 保存上下文
  2. 恢复上下文

 上述 恢复进程上下文 的操作,可以理解为把进程曾经保存的 进程数据都重新放到cpu当中,cpu在按照这些上下文数据,在去继续执行这个进程。

所以,如果是一个要执行很长时间的进程,不能一直在cpu上运行,当这个进程在当前时间片的执行时间到了,就要进行进程切换。因为这个进程要进行很长时间的执行,所以,这个进程注定是要被进行高频的进程切换的。那么该进程在运行期间,随时可能被中断,进行进程切换,在切换期间,就会有这个进程上下文 打包保存带走,和 恢复上下文的操作。    


进程的上下文保存在哪? 

    寄存器当中能存储的数据肯定是不多的,所以,保存的进程的临时数据也是不多的,所以,结合这种情况和上述 例子,那么,在执行进程切换的时候,进程的上下文数据就不能保存在 cpu 的寄存器当中。

那么,进程的上下文保存在哪?进程的 PCB 对象当中吗?

你可能会认为:是定义一个专门用于存储当前进程的 上下文文件的 结构体对象,把这个结构体对象放到 PCB 当中。

 其实这个做法是不太对的,因为这个做法太慢了。

cpu 在保存进程的上下文时,有自己的硬件方法:

x86保护模式——全局描述符表GDT详解_gdt全局描述符表 作用-CSDN博客

第十四课 局部段描述符的使用-CSDN博客

等等,关于操作系统硬件。


环境变量

环境变量介绍 

 环境变量是有系统提供的一组 name = value (键值对)形式的变量,不同的环境变量有不同的用户,通常具有全局属性。

环境变量 一般是指在操作系统中用来指定操作系统运行环境的一些参数

PATH环境变量

 我们在 配置 Java 环境,可能会遇到过配置环境变量的问题。

我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪里,但
是照样可以链接成功,生成可执行程序,原因就是有相关环境变量帮助编译器进行查找。

就像你在 开头 #include<> 引入的头文件,编译器是在哪里找到 头文件的位置的,靠的就是 环境变量当中对这个头文件 路径存储。


还有,在Linux 当中,你可能会有疑问,系统当中的命令,本质上也就是一个一个的软件,执行这个命令,也就是借助 bash 帮助我们解析这个命令,然后运行这个命令的程序。

但是,为什么我们输入指令,直接输入指令的名称就可以运行了;但是,我们运行自己写的程序还是需要 带上绝对目录,或者是 相对目录呢?

其实,这些系统当中的命令是在 /usr/bin 这个目录下的,这个目录是 系统默认的指令搜索的路径,所以,不需要带上 绝对路径 和 相对路径,让操作系统找到这个文件。

但是,我们自己写的 可执行文件,是在工作目录下存储的,需要带上 路径。


产生上述的原因就是,关于Linux在指令的搜索上,会帮我们 配置一个环境变量 --- PATH。这个环境变量是自动配置好的, 这个 PATH 当中包含了 一些 路径:

 他是以 ":" 作为分隔符,来定义了多个路径:

 这上面的每一条路径,就是系统在执行指令之时,在查找指令的可执行文件的默认路径。所以,在执行执行之时,就不会再 带上路径了。


我们可以使用 env 这个命令来查看到 系统当中所有的环境变量

 在 当中还可以 通过 getenv()函数,来获取到 传入的 字符串表示的 环境变量:
 

如在例子,利用 C 程序打印 PATH 环境变量的内容:

输出 PATH 内容: 

 因为获取到是 PATH 环境变量的内容,所以,不同的用户调用这个函数,得到的结果是不一样的,比如,下述登录 root 账户来运行这个程序:

这样的话,我们在 代码当中就可以判断,当前是哪一个用户(利用返回的字符串来控制),更具不同的用户就可以,实现不同的功能:
 

除了使用 getenv()函数之外,还可以使用 putenv()将环境变量拼接为字符串,然后将其替换原来的环境变量:

C语言putenv()函数:用于改变或增加环境变量的内容 - C语言网 (dotcpp.com)

 


 在 PATH 当中添加 和 删除路径

PATH=/xxx/xxx

使用上述方式,可以直接覆盖掉 PATH 当中的路径,以 上述我们输入的  /xxx/xxx 路径。

PATH=$PATH:/xxx/xxx

上述方式是在 PATH 原有的基础之上来,追加 一个 路径。

 如下例子所示,就追加了一个 路径 :
 

 此时,在我们刚刚配置的目录下的text 可执行文件,不需要路径都可以执行了:

 注意:PATH是一个内存级的环境变量,当你启动shell 之时,才会创建,如果你关机了,或者是退出 shell 了,那么这个环境变量就没了。当后序再次启动之时,这个环境变量其实是在 系统当中有配置文件的,启动就会按照配置文件来配置PATH。

像上述是在 Xshell 当中运行的,不需要Linux 操作系统重启,直接重启 Xshell 即可。

 HOME环境变量

 如果是以 root 用户登录的话,使用 pwd 和 echHOME 看到的路径是这样的:

 如果是以 普通用户登录的话,看到是如下路径:

也就是说,root用户刚登录的话,默认是在 .home 这个目录下的;而普通用户  刚登录的话,默认是在 自己的家目录下的。

当你在使用 shell 登录账户时候,shell 会识别 你当前登录的是什么用户,然后 填充 HOME 环境变量,当登录成功后,就默认帮你放到这个用户的 HOME 路径下了,因为有 HOME 的存在,shell 根据 HOME 给我们分配命令行解释器(bash)。

SHELL环境变量

这个环境变量当中存储的是,我们当前使用的是哪一个 shell,对应的可执行程序:

环境变量的组织方式 

 环境变量的组织方式,是以一个 environ 指针管理的 一个 char* [] 保存很多个 字符串 的指针数组存储的:
 

 命令行参数

 main函数是有参数的,如下所示:

int main(int argc , char* argv[])
{    

    return 0;
}

argv是一个字符串数组,前面的 argc 表示这个 argv 这个字符串数组存储的是什么内容:

我们发现,这个存储的是,我们运行这个 可执行程序,所使用 命令和 选项。是以空格来分隔 各个选项的:
 

 main()函数不是第一个被调用的函数,main函数是被  Statup()这个函数所调用的。main 函数也是被地调用的函数。所以他才能接收的到我们传入的 命令。其实本质上,我们传入的命令(输入的命令)其实就是一个 字符串。比如 ./text -a -b 本质上就是 输入了 "./text -a -b"这个字符串。然后 bash 命令行解释器就帮我们,按照空格分隔的方式,分隔(解释)了这个 命令。

而,我们使用的命令后面有不同的选项,这个选项是可以在 main 函数当中用 argv 这个字符串数组,采用 下标的方式访问到的,就和上述的例子是一样的。

 其实,我们使用命令,看上去有很多个选项,可以实现不同的功能,本质上那个就是用传入的不同的 字符串,分别判断这些字符串,然后实现不同功能

示例输出:
 

 所以,为了支持在命令行当中也可以更具我们自己的需要,来输入不同的参数,所以在main函数当中就可以 带 参数传入。这种方式是为指令,工具,软件等等提供命令行选项的支持。


main当中的 env 参数(理解 环境变量的 全局属性)

main函数当中有两个 核心向量表,一个是命令行参数表,另一个是环境变量表。 

 main()函数除了上述说的两个参数之外,还有参数, env 字符串数组:

int main(int argc , char* argv[], char* env[])
{    

    return 0;
}

这个 env 字符串数组 的结构 是和 argv 一样的。分隔方式也是一样,用空格来分隔,分隔的是一个一个的环境变量。

首先我们还是利用循环来打印一下 这个 环境变量表:
 

输出:

上述截图没有截完,其实这里的输出和 外部使用 env 命令是差不多的。把系统的环变量打印了

 所以,在理解上述两个 main 函数的 核心向量表之后,其实,当我们写了一个可执行程序,执行这个可执行程序时,不是简简单单的 把这个程序加载到内存当中,然后运行;

而是,一定有一个函数,去调用了 main()函数,把 main()函数最核心的两个向量表传入到main()函数的当中了。

 有上述打印的 和 env 指令一样的环境变量信息,那么为什么 text 这个程序能拿到 环境变量信息呢?

别忘了,text 是 bash 命令行解释器所创建的子进程,而上述打印的 环境变量,不是 运行了 text 可执行程序之后才有的,而是当我们打开我们 shell ,也就是打开终端之后,这些个 环境变量就被创建了,所以,这些环境是来自 bash 的。

所以,我们就有了一个结论,子进程是可以继承父进程的全部环境变量信息的

而,我们所运行的进程,都是子进程,bash 本身在启动的时候,会从操作系统 的配置文件当中,读取环境变量信息,bash 会在自己的上下文当中就会创建自己的 环境变量表。如果你需要,创建子进程,bash 就可以把这个 环境变量表给 创建的子进程来一份。子进程会继承父进程给的所有环境变量信息。

所以这也就意味着,从bash 运行开始,往后我们在终端上写的各种命令,执行的各种进程,都是bash 帮助我们创建的子进程,都会认识到 这些环境变量

因为都是 bash 这个命令行解释器,解释出,然后创建了 bash 的子进程,这个进程之间的关系,不管是 父子关系,还是兄弟进程之间都是有 bash  进程上下文当中的 环境变量信息的。

所以,这就是为什么 环境变量具有全局属性。 

假设,现在你想制定一些新的规则的话,就可以利用 环境变量的方式来制定 规则,这样的话,后续只用命令的方式运行的进程,就都会遵循这个 环境变量的 指定的规则了。 


如果,不想在main()函数当中传入参数,又想获得到 所以的环境变量的话;可以使用 C语言 在 unistd.h 这个头文件当中定义的 environ 这个第三方变来获取:
 

#include <stdio.h>
#include <unistd.h>

int main(int argc, char *argv[])
{
    // 声明 这个 变量
    extern char **environ;
    int i = 0;

    for(; environ[i]; i++){
        printf("%s\n", environ[i]);
    }

    return 0;
}

创建/取消  一个 环境变量 

使用 export 命令就可以创建一个 环境变量,如下例子所示:

上述,使用 env 也查到新创建的 环境变量的 存在。 

那么,当前就把 上述新创建的 环境变量,加入到了bash的上下文当中了。

此时我们在下述可执行文件当中,就可以在main()函数当中,打印出 我们上述所添加的环境变量了:
 

输出:
 


我们可以使用 unset 这个命令来删除一个 环境变量。 

我们上述所创建的 MY_VALUE 这个环境变量,在使用 unset 删除之后就不在了:

此时,env 也查不出 MY_VALUE 这个环境变量了。

 本地变量(shell变量)和 常规命令 , 内建命令

当我们在 终端上直接随便输入一个 全大写的 变量名(这个变量名是原本没有的),然后去赋值的话,能不能 创建一个新的环境变量呢?答案是不行的

 如上所示,我们使用 env 和 grep 过滤,不能查看到 Y_VALUE 的信息,那么这个 MY_VALUE变量是 不存在的吗?

这个 MY_VALUE 又是存在的,我们可以 使用 echo 查看到这个 变量的信息:
 

 其实这里的 MY_VALEU 不是环境变量,他是 本地变量


可以使用 set 命令来查看到 当前进程的所以变量(包括 环境变量 和 本地变量):

 

 


本地变量是不会被 子进程继承的,只会在本BASH当中有效。

像是在 BASH 当中还是有一些 自己定义的 本地变量的:
 

 


那么,现在有一个问题,我们上述说过了,我们在命令行当中运行的都是 BASH的 子进程,那么子进程是拿不到 BASH 当中的本地变量的

但是,我们上述在打印 本地变量的值的时候,使用的是 echo 这个命令来查看到的 本地变量的信息;这个 echo 不也是 BASH 所创建的  子进程吗?echo 为什么可以拿到 BASH当中的 本地变量的信息呢?

 其实,不是所以的命令都是要由 bash 来创建子进程的

LINUX 当中的命令其实分两批命令

  • 常规命令 -- 由创建子进程完成的。(这是我们所使用的很多命令)
  • 内建命令 -- 不创建子进程,由bash 亲自执行的命令。类似于bash 调用了自己实现的,或者是系统提供的函数。

 像上述的 echo 这个命令就是 一个 内建命令,所以,是在bash 当中自己执行,不需要创建子进程。所以,可以直接访问到 bash 上下文当中存储的本地变量的信息。


 其实,cd 命令也是一个内建指令cd 移动目录,其实本质上是bash 的执行目录发生了改变,所以,cd 如果只是一个 子进程的话,就不能更改的到 父进程 bash 的工作目录。只能是 cd 是内建命令,他更改的 工作目录其实和 bash 是一个工作目录;更改的其实是 bash 当中的 保存 工作目录的 本地变量。

 有一个函数 chdir()这个函数可以帮助你修改路径:

 谁调用这个接口,谁就会 把自己的工作路径改为 chdir ()这个函数传入的字符串对应的路径。

 像上述的例子,就可以实现  比如 :./text /  修改工作路径到  更目录的类似效果。

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1146518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

飞利浦双串口51单片机485网关

主要功能将PC端的数据接收下来&#xff0c;分发到不同的设备&#xff0c;也是轮询设备数据读取回来&#xff0c;打包回传到PC端&#xff0c;数据包包头包尾识别&#xff0c;数据校验&#xff0c;接收超时处理&#xff0c;将协议结构化处理&#xff0c;协议的改动不需要改动程序…

Python 算法高级篇:图的表示与存储优化

Python 算法高级篇&#xff1a;图的表示与存储优化 引言 1. 什么是图&#xff1f;2. 图的基本概念3. 图的表示方法3.1. 临接矩阵表示临接矩阵的优点&#xff1a;临接矩阵的缺点&#xff1a; 3.2. 邻接表表示邻接表的优点&#xff1a;邻接表的缺点&#xff1a; 4. 优化的存储方法…

开机流程、模块管理

一、开机流程 Linux系统组成 kernel 实现进程管理、内存管理、网络管理、驱动程序、文件系统、安全功能等功能rootfs 包括程序和 glibc 库 ​ 程序&#xff1a;二进制执行文件​ 库&#xff1a;函数集合, function, 调用接口&#xff08;头文件负责描述&#xff09; 开机流程…

13.6性能测试理论

一.什么是性能测试 1.定义: 测试人员借助性能测试工具(LoadRunner等),模拟系统在不同场景下(使用高峰期等),对应的性能指标是否达到预期. 2.性能测试和功能测试的区别: a.功能测试依靠人工,性能测试依靠工具. b)功能测试要求软件能正常运行,不管什么场景,性能测试要求软件…

[双指针] (二) LeetCode 202.快乐数 和 11.盛最多水的容器

[双指针] (二) LeetCode 202.快乐数 和 11.盛最多水的容器 快乐数 202. 快乐数 题目解析 (1) 判断一个数是不是快乐数 (2) 快乐数的定义&#xff1a;将整数替换为每个位上的和&#xff1b;如果最终结果为1&#xff0c;就是快乐数 (3) 这个数可能变为1&#xff0c;也可能无…

ESP-IDF编程指南

ESP-IDF 编程指南 - ESP32-C3 - — ESP-IDF 编程指南 v5.1 文档 (espressif.com) ESP-IDF 入门指南 | 乐鑫科技 (espressif.com) ESP-IDF 物联网开发框架 | 乐鑫科技 (espressif.com.cn)

【Git企业开发】第二节.Git 的分支管理

作者简介&#xff1a;大家好&#xff0c;我是未央&#xff1b; 博客首页&#xff1a;未央.303 系列专栏&#xff1a;Git企业级开发 每日一句&#xff1a;人的一生&#xff0c;可以有所作为的时机只有一次&#xff0c;那就是现在&#xff01;&#xff01;&#xff01;&#xff0…

一款功能强大的iOS设备管理软件Mazing 3中文版免费2024最新下载

Mazing 3中文版是一款功能强大的iOS设备管理软件&#xff0c;它可以帮助用户备份和管理他们的iPhone、iPad或iPod Touch上的数据。除此之外&#xff0c;它还可以将备份数据转移到新的设备中、管理应用程序、导入和导出媒体文件等。本文将详细介绍iMazing的功能和安全性&#xf…

解读deepLabV3+时遇到的问题总结

环境问题 python &#xff1a;3.10.12 ModuleNotFoundError: No module named ‘torchvision.models.utils 起初pip以下这个包&#xff0c;也没有解决问题&#xff1b;后来发现是版本的问题。 #from torchvision.models.utils import load_state_dict_from_url from torch.…

机器人入门(四)—— 创建你的第一个虚拟小车

机器人入门&#xff08;四&#xff09;—— 创建你的第一个虚拟小车 一、小车建立过程1.1 dd_robot.urdf —— 建立身体1.2 dd_robot2.urdf —— 添加轮子1.3 dd_robot3.urdf —— 添加万向轮1.4 dd_robot4.urdf —— 添加颜色1.5 dd_robot5.urdf —— 添加碰撞检测(Collision …

印度财团欲代工iPhone,路虎是前车之鉴,印度制造仍在梦中

随着印度财团塔塔收购纬创即将落寞&#xff0c;印度电子与科技国务部长强德拉谢克&#xff08;Rajeev Chandrasekhar&#xff09;为塔塔站台&#xff0c;表示两年内塔塔将制造iPhone并出口海外市场&#xff0c;印度制造将由此起飞。 一、印度制造在路虎上梦破 塔塔集团收购路虎…

手把手教你:如何用Java多线程模拟银行叫号服务

大家好&#xff0c;我是小米&#xff01;今天&#xff0c;我将和大家一起探讨一个非常有趣的话题——Java多线程模拟银行叫号服务。这不仅是一个有趣的编程练习&#xff0c;还可以帮助我们更好地理解多线程编程和并发控制。在这篇文章中&#xff0c;我将带领大家一步步实现一个…

cmd基本命令

一、cmd黑框是什么 cmd 是 Windows 命令提示符&#xff08;cmd.exe&#xff09;是 Windows NT 及以后的 Windows 系统下的一个用于运行 Windows 控制面板程序或某些 DOS 程序的shell程序&#xff1b;或在 Windows CE 下只用于运行控制面板程序的外壳程序。 二、打开步骤 wind…

Tornado downloadable工程和Tornado bootable工程

目录 Tornado downloadable工程Tornado bootable工程 Tornado downloadable工程和Tornado bootable工程是两个不同类型的Tornado项目。 Tornado downloadable工程 Tornado downloadable工程是指可以通过下载安装程序来安装的Tornado项目,通常用于Web应用程序。这种工程通常包…

相亲APP哪个好用?找对象的相亲软件哪个能脱单?

现在市面上的相亲APP非常多&#xff0c;质量也参差不齐&#xff0c;需要我们自己去辨别才能找到靠谱的&#xff0c;但是这很浪费时间。所以今天就分享几个我用过靠谱的相亲APP给大家参考&#xff0c;也算是提供一点经验。 1、一伴婚恋 这款相亲软件的优势在于&#xff0c;每个…

IOC课程整理-19 Spring Environment 抽象

1. 理解 Spring Environment 抽象 2. Spring Environment 接口使用场景 3. Environment 占位符处理 4. 理解条件配置 Spring Profiles 5. Spring 4 重构 Profile 6. 依赖注入 Environment 7. 依赖查找 Environment 8. 依赖注入 Value 9. Spring 类型转换在 Environment 中的运用…

使用dirhunt无需暴力破解即可扫描Web目录

Dirhunt 是一个针对搜索和分析目录进行优化的网络爬虫。如果服务器启用了“index of”模式&#xff0c;则该工具可以找到有趣的东西。如果未启用目录列表&#xff0c;Dirhunt 也很有用。它可以检测带有虚假 404 错误的目录、创建空索引文件以隐藏内容的目录等等。 Dirhunt 不使…

万字解析设计模式之工厂方法模式与简单工厂模式

一、概述 1.1简介 在java中&#xff0c;万物皆对象&#xff0c;这些对象都需要创建&#xff0c;如果创建的时候直接new该对象&#xff0c;就会对该对象耦合严重&#xff0c;假如我们要更换对象&#xff0c;所有new对象的地方都需要修改一遍&#xff0c;这显然违背了软件设计的…

麒麟KYLINOS2303版本上使用KDE桌面共享软件

原文链接&#xff1a;麒麟KYLINOS2303版本上使用KDE桌面共享软件 hello&#xff0c;大家好啊&#xff0c;今天给大家推荐一个在麒麟KYLINOS桌面操作系统2303版本上使用KDE桌面共享软件的文章&#xff0c;通过安装KDE桌面共享软件&#xff0c;可以让远程vnc客户端连接访问本机桌…

飞鼠异地组网工具基本使用教程

飞飞鼠异地组网工具基本使用教程 一、飞鼠工具介绍1.1 飞鼠工具简介1.2 飞鼠工具特点1.3 飞鼠工具使用场景1.4 飞鼠工具官网1.5 飞鼠工具版本介绍1.6 飞鼠工具节点类型 二、本次实践介绍2.1 本次实践简介2.2 本次环境规划 三、Docker环境安装工作3.1 master节点安装Docker3.2 子…