新手要如何让网站被收录,wordpress怎么使用插件下载失败,网站建设详细教程,网页设计学校官网文章目录 前言1.Linux下的软件安装1.1 什么是软件包1.2 如何安装软件1.3 如何卸载软件 2.vim2.1 vim的基本概念2.2 vim的基本操作2.3 vim正常模式命令集2.4 vim末行模式命令集2.5 vim的操作总结 3.Linux下的编译器#xff1a;gcc3.1 gcc的使用3.2 gcc是如何工作的3.2.1 预处理… 文章目录 前言1.Linux下的软件安装1.1 什么是软件包1.2 如何安装软件1.3 如何卸载软件 2.vim2.1 vim的基本概念2.2 vim的基本操作2.3 vim正常模式命令集2.4 vim末行模式命令集2.5 vim的操作总结 3.Linux下的编译器gcc3.1 gcc的使用3.2 gcc是如何工作的3.2.1 预处理(进行宏替换)3.2.2 编译生成汇编3.2.3 汇编生成机器可识别代码3.2.4 链接生成可执行文件或库文件 3.3 gcc选项3.4 函数库 4.Linux下的调试器gdb4.1 gdb的使用 5.Linux项目自动化构建工具make/Makefile5.1 原理5.2 项目清理文件的时间属性 5.3 Makefile的一些语法 6.模拟实现一个进度条6.1 缓冲区6.2 回车换行6.3 模拟实现6.3.1 process.h6.3.2 process.c6.3.3 main.c 总结 前言 前面已经介绍了一些指令内容本章将会继续介绍在Linux上安装软件已经编译器的使用代码的调试等等内容。
1.Linux下的软件安装
1.1 什么是软件包
在Linux下安装软件一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序。但是这样太麻烦了于是有些人把一些常用的软件提前编译好做成软件包(可以理解成windows上的安装程序)放在一个服务器上通过包管理器可以很方便的获取到这个编译好的软件包, 直接进行安装。软件包和软件包管理器就好比 “App” 和 “应用商店” 这样的关系。yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器主要应用在Fedora, RedHat, Centos等发行版上。
1.2 如何安装软件 安装软件一般都是root用户来进行这里是用sudo来进行了提权。一般想要安装什么软件直接上网搜索就可以了。
注意事项:
安装软件时由于需要向系统目录中写入内容一般需要 sudo 或者切到 root 账户下才能完成。yum安装软件只能一个装完了再装另一个正在yum安装一个软件的过程中如果再尝试用yum安装另外一个软件yum会报错。出现 “complete” 字样, 说明安装完成。
1.3 如何卸载软件 仍然是一条命令 sudo yum remove 软件名 2.vim
2.1 vim的基本概念 我们讲解vim的三种模式(其实有好多模式目前掌握这3种即可),分别是命令模式command mode、插入模式Insert mode和底行模式last line mode各模式的功能区分如下
正常/普通/命令模式(Normal mode) 控制屏幕光标的移动字符、字或行的删除移动复制某区段及进入Insert mode下或者到 last line mode 插入模式(Insert mode) 只有在Insert mode下才可以做文字输入按「ESC」键可回到命令行模式。该模式是我们后面用的最频繁的编辑模式。 末行模式(last line mode) 文件保存或退出也可以进行文件替换找字符串列出行号等操作。 在命令模式下shift: 即可进入该模式。要查看你的所有模式打开vim底行模式直接输入:help vim-modes 2.2 vim的基本操作
进入vim,在系统提示符号输入vim及文件名称后就进入vim全屏幕编辑画面 vim code.c 不过有一点要特别注意就是你进入vim之后是处于[正常模式]你要切换到[插入模式]才能够输入文字。 [正常模式]切换至[插入模式] 输入a 输入i 输入o [插入模式]切换至[正常模式] 目前处于[插入模式]就只能一直输入文字如果发现输错了字,想用光标键往回移动将该字删除可以先按一下「ESC」键转到[正常模式]再删除文字。当然也可以直接删除。 [正常模式]切换至[末行模式] 「shift : 」, 其实就是输入「:」 退出vim及保存文件在[正常模式]下按一下「:」冒号键进入「Last line mode例如 : w 保存当前文件 wq (输入「wq」,存盘并退出vim) q! (输入q!,不存盘强制退出vim) 2.3 vim正常模式命令集
插入模式 按「i」切换进入插入模式「insert mode」按“i”进入插入模式后是从光标当前位置开始输入文件 按「a」进入插入模式后是从目前光标所在位置的下一个位置开始输入文字 按「o」进入插入模式后是插入新的一行从行首开始输入文字。 从插入模式切换为命令模式 按「ESC」键。 移动光标 vim可以直接用键盘上的光标来上下左右移动但正规的vim是用小写英文字母「h」、「j」、「k」、「l」分别控制光标左、下、上、右移一格。 按「G」移动到文章的最后 按「 $ 」移动到光标所在行的“行尾” 按「^」移动到光标所在行的“行首” 按「w」光标跳到下个字的开头 按「e」光标跳到下个字的字尾 按「b」光标回到上个字的开头 按「#l」光标移到该行的第#个位置如5l,56l 按gg进入到文本开始 按shiftg进入文本末端 按「ctrl」「b」屏幕往“后”移动一页 按「ctrl」「f」屏幕往“前”移动一页 按「ctrl」「u」屏幕往“后”移动半页 按「ctrl」「d」屏幕往“前”移动半页 删除文字 「x」每按一次删除光标所在位置的一个字符 「#x」例如「6x」表示删除光标所在位置的“后面包含自己在内”6个字符 「X」大写的X每按一次删除光标所在位置的“前面”一个字符 「#X」例如「20X」表示删除光标所在位置的“前面”20个字符 「dd」删除光标所在行 「#dd」从光标所在行开始删除#行 复制 「yw」将光标所在之处到字尾的字符复制到缓冲区中。 「#yw」复制#个字到缓冲区 「yy」复制光标所在行到缓冲区。 「#yy」例如「6yy」表示拷贝从光标所在的该行“往下数”6行文字。 「p」将缓冲区内的字符贴到光标所在位置。注意所有与“y”有关的复制命令都必须与“p”配合才能完成复制与粘贴功能。 替换 「r」替换光标所在处的字符。 「R」替换光标所到之处的字符直到按下「ESC」键为止。 撤销上一次操作 「u」如果您误执行一个命令可以马上按下「u」回到上一个操作。按多次“u”可以执行多次回复。 「ctrl r」: 撤销的恢复 更改 「cw」更改光标所在处的字到字尾处 「c#w」例如「c3w」表示更改3个字 跳至指定的行 「ctrl」「g」列出光标所在行的行号。 「#G」例如「15G」表示移动光标至文章的第15行行首。 2.4 vim末行模式命令集 在使用末行模式之前请记住先按「ESC」键确定您已经处于正常模式再按「」冒号即可进入末行模式。
列出行号 「set nu」: 输入「set nu」后会在文件中的每一行前面列出行号 跳到文件中的某一行 「#」:「#」号表示一个数字在冒号后输入一个数字再按回车键就会跳到该行了如输入数字15再回车就会跳到文章的第15行。 查找字符 「/关键字」: 先按「/」键再输入您想寻找的字符如果第一次找的关键字不是您想要的可以一直按 「n」会往后寻找到您要的关键字为止。 「?关键字」先按「?」键再输入您想寻找的字符如果第一次找的关键字不是您想要的可以一直 按「n」会往前寻找到您要的关键字为止。 问题 和 查找有和区别操作实验一下 保存文件 「w」: 在冒号输入字母「w」就可以将文件保存起来 离开vim 「q」按「q」就是退出如果无法离开vim可以在「q」后跟一个「!」强制离开vim。 「wq」一般建议离开时搭配「w」一起使用这样在退出的时候还可以保存文件。 2.5 vim的操作总结
三种模式 正常模式 插入模式 底行模式 vim操作 打开关闭查看查询插入删除替换撤销复制等等操作。 有想了解更多关于vim的使用可以参考下面的链接 vim从入门到nb 补充如何注释 ctrlv进入视图模式然后通过hjkl来选择行再按shifti再按//再按esc就可以将选中行注释掉。 补充如何打开多个文件 在底行模式下输入vs 文件名 就可以了切换文件用ctrlww即可。 补充在打开文件时指定光标所在位置 gcc test.c 7 意思就是打开文件时光标处于第七行方便在编译出错时快速找到出错的行。 3.Linux下的编译器gcc
3.1 gcc的使用 在gcc后面跟上文件名就可以了。
3.2 gcc是如何工作的 其实具体过程与windows下生成可执行程序的过程是一样的都是经过 预处理进行宏替换)编译生成汇编)汇编生成机器可识别代码连接生成可执行文件或库文件)。
3.2.1 预处理(进行宏替换)
预处理功能主要包括宏替换,文件包含,条件编译,去注释等。预处理指令是以#号开头的代码行。实例: gcc –E hello.c –o hello.i选项“-E”,该选项的作用是让 gcc 在预处理结束后停止编译过程。选项“-o”是指目标文件,“.i”文件为已经过预处理的C原始程序。 在hello.i文件中将上面说的预处理功能进行了一遍但仍然是C语言上面展开的就是stdio.h头文件。
3.2.2 编译生成汇编
在这个阶段中,gcc 首先要检查代码的规范性、是否有语法错误等,以确定代码的实际要做的工作,在检查无误后,gcc 把代码翻译成汇编语言。用户可以使用“-S”选项来进行查看,该选项只进行编译而不进行汇编,生成汇编代码。实例: gcc –S hello.i –o hello.s 此步完成之后里面就不再是c语言了而是被转化为了汇编。
3.2.3 汇编生成机器可识别代码
汇编阶段是把编译阶段生成的“.s”文件转成目标文件读者在此可使用选项“-c”就可看到汇编代码已转化为“.o”的二进制目标代码了实例: gcc –c hello.s –o hello.o 此步完成后就转化为了最基本的二进制语言但是我们看到只是一堆乱码。 但是我们可以通过相关的软件来看。
3.2.4 链接生成可执行文件或库文件
在成功编译之后,就进入了链接阶段。实例: gcc hello.o –o hello 链接完之后就生成了可执行程序。.o文件系统库 可执行程序 在平时我们用gcc编译时gcc编译器是将所以过程一次性走完了直接得到了可执行程序。而通过-E、-S、-c等选项可以让其分开完成。 3.3 gcc选项 -E 只激活预处理,这个不生成文件,你需要把它重定向到一个输出文件里面-S 编译到汇编语言不进行汇编和链接-c 编译到目标代码-o 文件输出到文件-static 此选项对生成的文件采用静态链接-g 生成调试信息。GNU 调试器可利用该信息。-shared 此选项将尽量使用动态库所以生成文件比较小但是需要系统由动态库.-O0-O1-O2-O3 编译器的优化选项的4个级别-O0表示没有优化,-O1为缺省值-O3优化级别最高-w 不生成任何警告信息。-Wall 生成所有警告信息。 3.4 函数库
我们的C程序中并没有定义“printf”的函数实现且在预编译中包含的“stdio.h”中也只有该函数的声明而没有定义函数的实现那么是在哪里实“printf”函数的呢?最后的答案是系统把这些函数实现都被做到名为 libc.so.6 的库文件中去了在没有特别指定时gcc 会到系统默认的搜索路径“/usr/lib”下进行查找也就是链接到 libc.so.6 库函数中去这样就能实现函数“printf”了而这也就是链接的作用。 也就是说我们现在所写的代码都是站在巨人的肩膀上已经有人为我们写好了我们只是调用了别人已经写的接口或者函数。用以激励自我难度站在巨人的肩膀上还学不明白吗 那么我们所说的这批功能函数在哪里呢没错它就是库。在Linux中我们可以通过ldd指令来查看一个可执行文件依赖的那些库。 库的命名一般是去掉前缀和后缀以上面的例子来说就去掉lib再去掉.so.6实际上它就是C标准库 由此我们可以看出库文件就存放在/lib64/目录下的也就是说我们的可执行程序 代码 头文件提供方法的声明 库提供方法的实现。 所以所谓的开发环境安装实际上就是下载拷贝头文件和库到指定目录下这个目录可以被编译器自己找到。 函数库一般分为静态库和动态库两种。
静态库是指编译链接时把库文件的代码全部拷贝到可执行文件中因此生成的文件比较大但在运行时也就不再需要库文件了。其后缀名一般为“.a”。动态库与之相反在编译链接时并没有把库文件的代码拷贝到可执行文件中而是在程序执行时由运行时链接文件加载库,这样可以节省系统的开销。动态库一般后缀名为“.so”如前面所述的 libc.so.6 就是动态库。gcc 在编译时默认使用动态库。完成了链接之后,gcc 就可以生成可执行文件,如下所示。 gcc hello.o –o hello库中所有函数都有地址所谓的动态链接就是把要链接的库中的函数地址拷贝到我们的可执行程序的特定位置。gcc默认生成的二进制程序是动态链接的这点可以通过 file 命令验证。 动态库的优缺点 优点形成的可执行程序的体积比较小比较节省资源。 缺点稍慢一些 静态库的优缺点 优点无视库可以独立运行缺点体积太大浪费资源 gcc的默认链接的方式是动态链接为什么呢就是因为静态库的缺点无法接受所以选择了动态链接。 我们下载的开发环境默认要为我们做什么 下载开发环境includelib设置合理的查找路径规定我们形成的可执行程序的链接方式 为什么要有库呢是为了大家不必实现一些不必要的功能使用现成的就好不然你实现一遍他又实现一遍那到底是使用谁的呢所以就直接让大家使用同一份写好的就好了。
4.Linux下的调试器gdb
程序的发布方式有两种debug模式和release模式Linux gcc/g出来的二进制程序默认是release模式要使用gdb调试必须在源代码生成二进制程序的时候, 加上 -g 选项 这个意思就是此时没有发现debug的特征所以可以知道编译完成之后的可执行程序是release版本的。 重新编译之后就可以进入调试了。 如果想让你的代码以debug的形式发布必须给gcc添加-g选项。
4.1 gdb的使用 gdb binFile 退出 ctrl d 或 quit 调试命令 listl 行号显示binFile源代码接着上次的位置往下列每次列10行。listl 函数名列出某个函数的源代码。r或run运行程序。n 或 next单条执行。s或step进入函数调用break(b) 行号在某一行设置断点break 函数名在某个函数开头设置断点info break 查看断点信息。finish执行到当前函数返回然后挺下来等待命令print§打印表达式的值通过表达式可以修改变量的值或者调用函数p 变量打印变量值。set var修改变量的值continue(或c)从当前位置开始连续而非单步执行程序run(或r)从开始连续而非单步执行程序delete breakpoints删除所有断点delete breakpoints n删除序号为n的断点disable breakpoints禁用断点enable breakpoints启用断点info(或i) breakpoints参看当前设置了哪些断点display 变量名跟踪查看一个变量每次停下来都显示它的值undisplay取消对先前设置的那些变量的跟踪until X行号跳至X行breaktrace(或bt)查看各级函数调用及参数infoi) locals查看当前栈帧局部变量的值quit退出gdb eg 增加断点
5.Linux项目自动化构建工具make/Makefile
会不会写makefile从一个侧面说明了一个人是否具备完成大型工程的能力一个工程中的源文件不计数其按类型、功能、模块分别放在若干个目录中makefile定义了一系列的规则来指定哪些文件需要先编译哪些文件需要后编译哪些文件需要重新编译甚至于进行更复杂的功能操作makefile带来的好处就是——“自动化编译”一旦写好只需要一个make命令整个工程完全自动编译极大的提高了软件开发的效率。make是一个命令工具是一个解释makefile中指令的命令工具一般来说大多数的IDE都有这个命令比如Delphi的makeVisual C的nmakeLinux下GNU的make。可见makefile都成为了一种在工程方面的编译方法。make是一条命令makefile是一个文件两个搭配使用完成项目自动化构建
5.1 原理
make是如何工作的在默认的方式下也就是我们只输入make命令。 make会在当前目录下找名字叫“Makefile”或“makefile”的文件。如果找到它会找文件中的第一个目标文件target在上面的例子中他会找到“hello”这个文件 并把这个文件作为最终的目标文件。如果hello文件不存在或是hello所依赖的后面的hello.o文件的文件修改时间要比hello这个文件新可以用 touch 测试那么他就会执行后面所定义的命令来生成hello这个文件。如果hello所依赖的hello.o文件不存在那么make会在当前文件中找目标为hello.o文件的依赖性如果找到则再根据那一个规则生成hello.o文件。这有点像一个堆栈的过程当然你的C文件和H文件是存在的于是make会生成 hello.o 文件然后再用 hello.o 文件声明 make的终极任务也就是执行文件hello了。这就是整个make的依赖性make会一层又一层地去找文件的依赖关系直到最终编译出第一个目标文件。在找寻的过程中如果出现错误比如最后被依赖的文件找不到那么make就会直接退出并报错 而对于所定义的命令的错误或是编译不成功make根本不理。make只管文件的依赖性即如果在我找了依赖关系之后冒号后面的文件还是不在那么对不起 我就要罢工了。 这里就是你要生成mybin可执行程序需要依赖hello.c来生成通过什么样的方式来生成呢通过gcc hello.c -o mybin来生成。
5.2 项目清理
工程是需要被清理的 像clean这种没有被第一个目标文件直接或间接关联那么它后面所定义的命令将不会被自动执行不过我们可以显示要make执行。即命令——“makeclean”以此来清除所有的目标文件以便重编译。但是一般我们这种clean的目标文件我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是总是被执行的。可以将我们的 hello 目标文件声明成伪目标测试一下。 这样看好像还不如直接编译对于只编译一个文件确实是这样的如果是编译十个文件或者更多它的优势就体现出来 我们只需要make就可以直接编译了不然就需要将所有文件都得写一遍没编译一次就得将所有文件都斜写一遍很麻烦。 .PHONY是伪目标的意思被伪目标修饰的文件总是被执行的。我们来看此时是无法进行多次编译的 .当经过.PHONY修饰后就可以进行多次编译了。 这是为什么呢这是因为make和makefile是不允许进行多以编译的因为它会识别你的文件是否进行过更改如果没有被更改它是不会进行编译的只会编译修改过的文件因为没有修改过的文件进行反复编译是没有意义的同时也可以提高编译速度。 那么它又是如何辨别出来一个文件是否被修改过呢这是因为每个文件的属性中都有记录本文件的最后修改时间即使如此哪有是如何对比出来的呢它实际上是与这个源文件所生成的可执行程序的生成时间进行比较的。我们知道一定是现有源文件再有可执行程序那么源文件的时间一定是小于可执行程序文件的时间的而一旦源文件进行了修改那么它的时间就会大于可执行程序文件的时间make和makefile就是由此进行对比然后绝对一个文件是否被再次编译。
文件的时间属性 那我们就来看看文件的几个时间属性 这里就有一个问题了Modify与Change都是修改那么它们有什么区别呢我们知道一个文件 内容 属性Modify就是针对内容的修改Change是针对属性的修改。 那么make和makefile是通过比较哪一个时间来得出的结论呢我们可以看出如果一个文件内容修改了那么文件的大小就会变化那么跟着它的Change就会因为文件大小这个属性发生了改变而跟着改变。而当Change改变时只是属性发生的变化而内容可能没有发生变化比如文件的权限发生了变化。由此可以得出make和makefile是根据Modify的时间来进行比较的。 但是我们发现我们在查看一个文件后它的访问时间并没有发生改变。这又是为什么呢 我们知道文件都是存放在磁盘中的而更改访问时间的本质就是访问磁盘但是我们知道访问磁盘是比较满的而我们又需要经常查看文件这变相就减慢了系统的效率因此在现在使用的Linux系统中将Access时间的更改增加了一些策略比如达到多少次才更新也可能过了一定的时间才更新。 那么我们有没有在不改变文件内容的前提下更改文件时间呢那就是我们之气使用创建文件的指令——touch。我们可以通过man touch来查看touch指令的使用方式。
5.3 Makefile的一些语法 make和makefile是具有推导功能的。我们先修改一下Makefile文件。 我们将hello.c改为hello.o。 也就是说我们是要根据hello.o文件生成mybin可执行程序但是我们没有hello.o文件只有.c文件。此时Makefile就会自动通过.c文件进行推到出来.o文件再生成mybin可执行程序。 在Makefile文件中加上后就不会显现出指令。 在Makefile中也支持书写变量。 可以理解为是一种替换。这样写的好处就是我们每次只需要改上面的变量下面的会自动跟着变不再需要全部重新写了。 Makefile的依赖方式还可以进行简写。 这样写的好处是当多个文件一起进行编译时下面只需要些一个$^就可以了。
6.模拟实现一个进度条 在具体实现进度条之前还需要先了解一下缓冲区的概念。
6.1 缓冲区 上面代码的区别仅仅是是否有\n可以结果输出却不一样这是为什么呢我们知道程序是从上往下进行的那么printf一定比sleep先执行可是在下面的结果中却是先睡眠了两秒才输出了hello Linux那么在这期间hello Linux跑哪去了呢 先说后面的问题在这期间hello Linux是存放到了stdout的标准输出流缓冲区中。如何验证呢我们可以通过fflush来验证它的作用是立即刷新缓冲区。 所以所有的输出都是先存放在输出缓冲区中在刷新缓冲区后才会显示出来。 \n是一种刷新的策略–行刷新。 6.2 回车换行 回车换行我们都知道它是跑到下一行的开头有两个步骤一个是先换到下一行另一个是跑到开头。在我们编代码时\n就是回车换行的行为而\r就仅仅只是回车的作用也就是将光标换到开头。 也就是说使用\r时比如先输出9再回车输出8那么后面的8就会将前面输出的9覆盖掉。 这样就可以完成一个倒计时的效果。大家可以自己试验一下博主就懒的录制视频了。 但是我们要注意的是输出到我们屏幕上的数据实际上字符而如果我们将数据从10开始输出按照上面所讲第一次输出的是10第二是9要覆盖开头第一个字符那么就变成了90这是不是就出现问题了所以我们可以修改输出格式为两个字符为一组 倒计时数字一般都是靠边输出的如果解决呢这个也很简单只需要在这这里加上-就可以了。
6.3 模拟实现
6.3.1 process.h
#pragma once
#includestdio.h
#includeunistd.h
#includestring.h
void process();
void process_v2();
void process_v3(); 6.3.2 process.c 1#includeprocess.h2 3 const char* str /-|\\;4 5 6 //void process()7 //{8 // int rate 0;9 // char bar[101] {0};10 // int len strlen(str);11 //12 // while(rate 100)13 // {14 // printf([%-100s][%d%%][%c]\r,bar,rate,str[rate%len]);15 // fflush(stdout);16 // usleep(1000*20);17 // bar[rate] #;18 // }19 // printf(\n);20 //}21 22 23 void process_v2(int rate) 24 {25 static char bar[101] {0};26 int len strlen(str);27 28 if(rate 0 rate 100)29 {30 printf([%-100s][%d%%][%c]\r,bar,rate,str[rate%len]);31 fflush(stdout);32 usleep(1000*20);33 bar[rate] #;34 if(rate 100) bar[rate] \0;35 }36 } 37 38 void process_v3(double rate)39 {40 static char bar1[101] {0};41 int len strlen(str);42 43 static int cnt 0;44 cnt;45 cnt cnt len ? 0 : cnt;46 47 if(rate 0 rate 100)48 {49 printf([%-100s][%.1f%%][%c]\r,bar1,rate,str[cnt]);50 fflush(stdout);51 52 if((int)rate 99)53 {54 bar1[(int)rate] ;55 bar1[(int)rate] ;56 }57 else 58 {59 // bar[(int)rate] ;60 bar1[99] ;61 }62 }63 }6.3.3 main.c 1 #includeprocess.h2 #define TARGET 1024*10243 #define DNUM 1024*104 5 typedef void (*callback_t)(int);6 7 void Download(callback_t cb)8 {9 int target TARGET;10 int total 0;11 12 while(total target)13 {14 usleep(1000*40);15 total DNUM;16 double rate total*100 / target; 17 cb(rate);18 }19 printf(\n);20 }21 22 void Down()23 { 24 int target TARGET;25 int total 0;26 27 while(total target)28 {29 total DNUM;30 process_v2(total*100 / target);31 usleep(1000*20);32 }33 34 printf(\n);35 }36 37 int main()38 {39 Down();40 Download(process_v3);41 return 0;42 }
总结 本文主要是讲解了如果在Linux命令行模式下如果进行编写代码相信经过本文的介绍后大家已经能对Linux下的编程有了一定的了解让命令行模式在大家面前不再陌生那么关于如果在Linux下编写代码的内容就到此结束往后就会讲解有关Linux操作系统的一些知识。希望能与大家一同进步噢。 如果大家发现有什么错误的地方可以私信或者评论区指出喔。我会继续深入学习Linux希望能与大家共同进步那么本期就到此结束让我们下期再见觉得不错可以点个赞以示鼓励