date
icon
password
博客链接
Pin
Pin
Hide-in-Web
Hide-in-Web
网址
type
slug
tags
category
bottom
bottom
Hide-in-Config
Hide-in-Config
comment
status
summary
🔥
🎉欢迎大家来到我的博客!! 本篇笔记已更新完毕【2025.4.18】 🎉
建议大家使用电脑来查看笔记内容,会有最好的显示效果。
🚧
看到弹幕中很多人要老韩的课件,可以通过添加韩老师的微信向他购买(6 块钱),他会分享给你们一个网盘链接(是以文件夹形式上传的,不是压缩包,因此全部下载下来非常麻烦)。既然韩老师是将资料商用卖出了,我这里就不好分享该资源了。不过我的笔记中也记录了很多老师资料中没有的知识点,而且是站在初学者的角度一步步探索的,因此应该也会对大家有帮助。

Linux 学习方法——树立正确的认知

  1. 初学时不要太抠细节,要把握整体,高屋建瓴,在整体框架都熟悉以后再慢慢来抠细节;
  1. 不要求记住所有的指令,但是对这些指令要有印象,要能学会在百度、手册中查询命令的能力;
  1. 如学习很多工科的知识一样,在学习 Linux 的时候,要先 know how,再 know why。即先知道如何去做,有些知识点的理解可能涉及到后面更高级的知识,一时半会儿理解不了,在后面的学习中会慢慢理解为什么要这么做;
  1. 适当地囫囵吞枣。在学习 Linux 的过程中会遇到很多难题,这些难题不一定会一下子想到如何解决,我们可以将疑问先放着,等学到后面的知识点时再会看这个疑问,也许就小菜一碟了;
  1. Linux 是实操性的东西,不像其他编程语言一样有很多的编程思想和语法,我们需要做的就是将 Linux 的常用指令玩的非常溜(即常用的操作要非常熟练);

绪论


📝 Class Notes

Linux 课程内容
notion image
notion image
Linux 未来职业方向
notion image
Linux 运维工程师主要是负责以下一些工作的:
  1. 服务器规划;
  1. 服务器优化;
  1. 服务器日常监护;
  1. 故障处理;
  1. 数据的备份和恢复;
  1. 日志的分析;
  1. 服务器瘫痪后如何迅速的恢复;
运维工程师通常不是只负责一台设备的,而是负责一个集群的。
Linux 嵌入式工程师主要负责各种驱动的开发和各种嵌入式系统中功能的开发(以 C/C++ 语言为多)。
Linux 的应用领域
Linux 在桌面领域是薄弱环节,但近些年来随着 ubuntu、 fedora 等优秀桌面环境的兴起,linux在个人桌面领域的占有率在逐渐的提高。
notion image
Linux 的创始人
Linux 创始人是 Linus Torvalds(林大神),他也是 Git 和 github 的创作者。他研发的 Linux0.01 版本的源码不到 1 万行(老师反复强调😅)。
学完 GIT 后补充:
Linus Torvalds 真可谓是一个大神,配得上“大佬”称号。
在 1991 年开发了 Linux 后,直到 2002 年,一直都是自己手动合并代码(当别人有新的 idea 并将修改后的代码发送给他时,他需要进行合并),对 Linux 进行更新,积极维护这个开源系统。后来,Bitkeeper 软件(版本控制系统)的创作公司 BitMover 出于人道注意精神,援助了林大神,授权 Linux 社区免费使用它们的软件,但要求其不能破解。
后来,一位 Linux 社区的程序员没忍住破解了 BitKeeper 还发文炫耀,BitMover 公司发现后便收回了在 Linux 中的免费使用。
于是,林大神花了两周时间(据说是 10 天)创建了分布式版本控制系统 Git 😅,一直延续至今,而且 git 还是开源的。
2008 年,Chris Wanstrath、PJ Hyett、Tom Preston-Werner 等人在 git 的基础上创办了 github ,作为 git 的上层应用平台(“git 的社交网络”),降低了 git 的使用门槛,极大拓展了开源社区。林大神开源的格局着实令人钦佩。
Linux 的吉祥物
韩老师说是因为创始人的妻子在 Linux 开发时被企鹅咬了一口,因此 Linux 的标志物就是一只企鹅。
操作系统
Linux 与 Windows、macos 等一样,是一个操作系统。
什么是 Linux 的发行版
Linux 是一个内核,而对其进行包装以后就会成为 Linux 发行版,如 Ubuntu(乌班图)、Centos、Redhat(红帽)等。
Unix 与 Linux 的关系
Unix 是由上世纪 70 年代美国贝尔实验室的两位大佬(Ken Tompson、Dennis Richres)开发的(原来是 B 语言,后来又被他们重构为 C 语言),在上世纪 80 年代被很多公司采用作为操作系统。
但 Unix 只能在大型服务器上使用,普通用户玩不起,因此在 Richard Stallman 的倡导下(他认为普通用户也该拥有享用并修改软件的权利),发起了 GNU 计划。
而 Linux 的创始人 Linus Torvals (当时在研究生阶段)就加入了这个计划,并在参考了很多人的想法后创建了 Linux 内核。
notion image
notion image

Linux 基础

📝 Class Notes

Linux 安装
Linux 需要在虚拟机上进行安装。虚拟机与 windows 的关系如下:
notion image
如果直接在 windows 中安装,如果配置失败,很可能使得电脑无法使用,但在虚拟机中配置失败,只需要新建一个虚拟机即可。
因此在安装 Linux 之前需要先安装 虚拟机,韩老师使用的是 Vmware 虚拟机,在安装虚拟机前,需要先启用“虚拟化”。电脑是否有开启虚拟化可以通过下面的操作检查:
首先按下组合键 Ctrl+Alt+Del 选择任务管理器打开,点击侧边栏的性能按钮,再点击 CPU,然后就可以在 CPU 信息栏中看到是否有启用虚拟化了:
notion image
如果没有虚拟化,请按照韩老师提供的方法进行操作。确认好虚拟化后,就可以安装 vmware 了,vmware 在过去是要收费的,不过在 2025 年已经免费了,它被博得(broadcom)公司收购,因此需要在博得公司下载。vmware 免费后,下载链接听说巨难找,我是参考知乎的这篇文章(好事|虚拟机VMware彻底免费了(附下载方法) - 知乎)找到下载链接的,大家可以前往这篇文章查看下载方法(记得在下载前要先注册一个博得账号)。【这里提供一个我当时下载的链接(不知道你们看到后还能否用):vmware 下载链接
虚拟机安装完成后,大家按照老师课程中的介绍一步步安装系统即可,一定要一步一步跟着做,不要提前,否则有的是苦吃。
如何找回 root 密码
如果忘记了虚拟机的 root 密码,可以通过以下方式找回:
  1. 首先重新启动虚拟机,在以下页面中按下键盘上的 e 键进入编辑页面;
notion image
  1. 在编辑页面中,将光标往下移动(键盘上的向下箭头)找到以 “Linux16” 开头的句子,在绿箭头所示的位置先输入一个空格,然后输入 init=/bin/sh,按下 Ctrl+X 进入单用户模式(不用按下回车)【单用户模式在后面会介绍】;
notion image
  1. 在单用户界面中输入 mount -o remount,rw / (mount 是挂载的意思)后,按下回车键,再输入 passwd (password 的缩写)就可以进入修改密码的进程了;
  1. 重复输入两次你想要修改的密码即可完成修改;
    1. notion image
  1. 修改完成后,输入 touch /.autorelabel ,回车,再输入 exec /sbin/init ,系统就会自动修改密码了。
notion image
💡
在输入 exec /sbin/init 命令后,界面中可能会显示 smbus controller not enabled 这一串字符,然后光标就会在下一行开头闪烁,没有其他语句出现,这时候不用着急,等待 1~2 分钟密码就会重置成功了。
Linux 网络连接的三种方式
三种连接方式分别为 桥接模式NAT 模式仅主机模式
桥接模式下,虚拟机内的 Linux 系统可以和外界设备进行通信(有来有回),但这种方式的缺点是容易与其他设备的虚拟机发生 IP 地址冲突;
NAT 模式下,虚拟机内的 Linux 系统可以获取到外接设备发送来的消息,但外部设备无法访问虚拟机内的系统,此时虚拟机与主机共用 IP 地址;
仅主机模式下,虚拟机内部的 Linux 系统无法和外界有任何交流,只能和主机交互。
虚拟机的基本操作(克隆、快照、迁移和删除)
克隆:
由于创建一个新的虚拟机比较麻烦,因此,可以通过克隆的方式快速创建一个新的虚拟机。
克隆有两种方式可以实现:
  1. 在 vmware 中,右键虚拟机系统,在“管理”项中会看到一条“克隆”的功能(如下图所示),点击即可复制一个新的虚拟机;
    1. notion image
  1. 将存放虚拟机文件的文件夹整体复制一份,粘贴到其他位置,然后打开 vmware 软件将复制后的虚拟机添加进来。
快照:
notion image
虚拟机快照过程有点类似于 windows 的创建系统还原点,只不过虚拟机系统中快照可以有多张。
需要注意的是,虚拟机快照会占用虚拟机的内存,因此使用虚拟机快照往往都是有特定的目的的,随意乱照会造成内存的浪费。
‼️
建议大家在创建好一个虚拟机系统后就先快照保存 Linux 的初始状态,这样后面学习过程中如果虚拟机出了什么故障,也可以通过快照回来。
迁移:
即虚拟机克隆的第二种方式,把存放虚拟系统的文件夹整体拷贝或者剪切到其他位置即可实现迁移。
删除:
虚拟机的删除可以直接通过 vmware 实现,进入 vmware 后,点击菜单->从磁盘删除即可, 或者直接手动删除虚拟系统对应的文件夹即可。
【开始课程前】最基础的三个 Linux 终端命令和两个快捷键
以下的三个命令均在 Linux 的终端中运行,后面韩老师在讲解课程的时候会用到,因此提前知道会比较好。
这里只介绍简单用法,在后面的课程中会详细介绍这些指令。
pwd 命令
pwdprint work directory 的缩写,表示输出当前的工作目录。输出结果通常是反斜杠开头的。
notion image
cd 命令
cdchange directory 的缩写,表示更改文件目录地址。通过cd 路径 即可实现跳转,比如我们要进入 home 文件夹下,就可以输入 cd /home 过程如下:
💡
Linux 中的路径以反斜杠 / 分隔,而 Windows 中的路径使用 \ 分隔。
notion image
ls 命令
lslist files 的意思,表示列出当前目录下的文件。使用方法如下图所示:
notion image

Ctrl+C用于强制终止正在运行的进程。当输入了某条指令后,你突然间不想运行了,可以按下这个快捷键。
Ctrl+Backspace:删除光标前的整个单词(以空格或符号分隔),有时候用键盘上的删除键删不掉某个字符时,试试删除键和 Ctrl 一起按下。
共享文件夹的设置
在 Linux 中可以设置共享文件夹,即 Windows 系统和 Linux 系统共用一个文件夹,当 Windows 对这个文件夹进行修改的时候(比如在文件夹下添加了一张图片), Linux 系统也会同步发生变化,同理,在 Linux 系统进行操作时,Windows 系统也会同步。
共享文件夹的设置需要使用到 vmtools 工具,在 Centos 7.6 之后的版本中,vmtools 已经内置了(我用的是 7.6 的版本,在 7.6 之前是否已经内置不确定),无需手动安装。
💡
在后面的课程中会介绍如何远程上传共享的文件夹,因为在实际应用中,我们接触的 Linux 系统通常都不是安装在自己电脑上的,只能用电脑远程访问。
Linux 目录结构
在 Linux 的世界中,一切皆文件。所有的硬件都是通过文件来进行存储的,每种类型的文件都有其对应的文件夹,cpu 有 cpu 的文件夹,U 盘有 U 盘的文件夹。熟记 Linux 的目录结构是基本中的基本
与 Windows 不同,在 Linux 系统中,使用反斜杠 “/” 表示路径分隔。在地址的开头使用反斜杠 “/” 表示 根目录,如 cd /bin 就表示进入根目录下的 bin 文件夹。
🚧
在未来使用 Linux 系统时,不会像现在打开虚拟机一样有可视化的文件路径,系统的目录结构只能够在终端中通过文件树来查看,因此知道每个目录的作用十分重要。
下面是 Linux 系统中的目录结构:
常用路径

/bin
binary 的缩写,这个目录中存放着最经常使用的命令,如 ls 指令。
/home
该路径中存放着普通用户的主目录。每个用户在该路径下都会有一个对应的文件夹,文件夹的名称即为用户的名称,新建或删除用户,路径下文件夹会同步进行变化。
/root
该目录为系统管理员,也称作是超级权限者的主目录。
/etc
etc 是拉丁语 etcetera[et'setərə] 的缩写,意思是等等。
  • 最初,/etc 目录用于存放系统中杂项配置文件,即那些不属于其他特定目录的文件。
  • 现在,/etc 主要存放系统的配置文件,如安装 mysql 库所需要的 my.conf 文件。

/etc/group :该文件内存放的是用户分组的文件;
/usr
Unix System Resources 的缩写,用于存放用户的很多应用程序和文件,类似于 Windowsprograms files 目录,是一个非常重要的路径。
/usr/local
这是给另一个主机额外安装软件所提供的目录,一般存储的是通过编译源码方式安装的程序。
/media
Linux 会自动识别一些设备,如 U 盘,光驱等,当识别后,Linux 会把识别的设备挂载到这个目录下。
/mnt
mntMount(挂载)的缩写,是临时挂载点,,用于手动挂载文件系统(如硬盘分区、网络共享等)。
系统提供该目录是为了让用户临时挂载别的文件系统,我们可以将外部的存储挂载在 /mnt 上,然后进入该目录就可以查看里面的内容了,比如之前我们创建的共享文件夹。
/var
varvariable 的缩写,主要用于存储经常变化的(variable)数据。通常会将经常被修改的文件(如日志文件等)存放在该路径下。
轻易不能动路径

/boot(开机、启动) :
存放的是启动 Linux 的核心文件,包含一些链接文件和镜像文件。
/proc
procProcess(进程)的缩写,它是一个虚拟目录,提供了内核和进程运行时的信息。它包含的文件和目录并不是真实的文件,而是系统运行时数据的映射。
/srv
service 的缩写,用于存放一些服务启动之后需要提取的数据。
/sys
system 的缩写,Linux 2.6 版本新出现的目录,安装了一个新的文件系统 sysfs
 
其他路径

/sbin
前缀 s 表示 super ,该路径下一般存放的是管理员使用的系统管理程序。
/lib
liblibrary 的缩写,系统开机所需要最基本的动态连接共享库,其作用相当于是 Windows 里的 dll 文件,几乎所有的应用程序都会用到这些文件。
/lost + found
lost+found 就是文件夹的名称,Linux 中的文件夹名字可以使用特殊字符,并且除去 ”/“ 和 \0(空字符)(表示字符串结束)以外,都可以用于文件名。
该文件夹一般是空的,当系统非法关机后, 这里就存放了一些文件。
/tmp
tmptemporary 的缩写,用于存放一些临时文件的。
/dev
devices 的缩写,类似于 Windows 的设备管理器,将所有硬件通过文件形式来存储。
/opt
optional(可选的)的缩写,用于存放第三方应用程序可选软件包。这些软件通常是独立的,不依赖于系统的包管理器(如 APT 或 YUM),默认为空。
/selinux
前缀 sesecure 的缩写,是一种安全子系统,限制程序只能访问特定文件,有三种工作方式,可自行设置。
 
Linux 远程登录(Xshell 和 Xftp 的安装)
首先介绍以下为什么要进行远程登录?
  1. 开发 Linux 项目的时候,是以开发小组的形式进行的,因此将项目放在一台设备上,小组成员以远程登录的形式进行访问;
  1. 在 Linux 项目开发后,往往都是发布在公网上运行的,如果要对项目进行管理或修改,需要进行远程登录;
如何进行远程登录?
远程登录首选的软件是 Xshell,对于个人学习和学校教育而言是免费的(商用收费),它的速度流畅,且对中文支持很好,是工程师首选的软件。直接在浏览器搜索 “xshell 官网”动点脑筋就可以下载到了。
在进行远程登录配置的时候学习到了两个指令:
  1. ifconfig 指令;
    1. 在 Linux 的桌面右键点击终端,在终端中输入 ifconfig 即可查询到 LinuxIP 地址。
  1. ping [IP地址] 指令;
    1. Windows 中打开 cmd 窗口输入 ping [IP地址] 即可测试主机能否与 IP 地址指向的设备进行通讯。
  1. 【补充】ipconfig 指令
    1. ipconfig 是在电脑主机的终端中输入的,用于查询主机的 IP 地址。
如何进行远程文件交互?
远程文件交互即在主机和远程登录的设备之间进行文件的移动、复制和删除,使用的软件是 Xftp,也是 Xshell 同公司开发的。
🚧
在远程登录或进行文件交互的过程中注意:
连接设备时,有两个选项可供选择:
  • 一次性接收,下次还要输入用户和密码;
  • 接收并保存,下次就不用输入用户和密码了(实际工作中建议选择此选项)。
⚠️
注意,如果后面学习过程中出现命名 Linux 打开了却一直连接不上 Xshell 的情况,可以在 Linux 的终端中输入我们前面学习的指令 ifconfig 查看 Linux 的 IP 地址是否发生了修改。

Linux 指令与常用操作

📝 Class Notes

在后面的笔记中,我所说的 Linux 终端既可以是 Vmware 虚拟机中打开的终端,也可以是 Xshell 登陆后的终端。
Vim 编辑器
Vim 编辑器是 Linux 内置的编辑器,在 Linux 终端或是 Xshell 中都可以使用(使用方式相同)。
下面以 Xshell 中使用为例。下面的所有内容均在 Linux 终端或 Xshell 中进行。Linux 终端通过鼠标右键点击“终端”进入。

Vim 指令介绍:
  1. 打开文本文件:
    1. 要使用 vim 编辑文件,我们需要先利用 vim 打开一个文本项目。打开方式很简单,直接使用 vim 项目名称vi 项目名称 即可打开(项目名称需要包含后缀名),比如在主目录下我们有一个文本文件名为 Hello.py ,如果我们要使用 vim 编辑它,就可以使用 vim Hello.py 来进入文件内部;
  1. 创建文本文件:
    1. 要创建文本项目,同样可以使用 vim 命令来完成,与打开文本文件一样,使用 vim 项目名称vi 项目名称的方式即可创建一个文本文件。如 vim test.py 创建一个名为 testpython 文件,vim hello.java 创建一个 java 文件。
notion image
💡
其实通过上述两个指令也能发现,vim 项目名称 在目录下没有该文件时会创建此文件,有该文件时会打开此文件。
💡
在介绍 vim 的其他指令之前,需要先介绍一下 vim 的三种工作模式:
  1. 正常模式;
    1. 在使用 vim 打开文件后,默认就是正常模式。
  1. 插入模式;
    1. 插入模式下可以进行文本编辑,在正常模式中输入字母 i, I, o, O, a, A, r, R 中的一个即可进入插入模式。在插入模式下写文件与记事本中类似。
      按下键盘左上角的 Esc 键即可退出插入模式,返回正常模式。
  1. 命令行模式;
    1. 在正常模式中输入英文冒号 : 即可进入命令行模式,在冒号后面输入指令即可执行一些操作;
      如果是在插入模式中,需要先使用 Esc 键退出插入模式,返回正常模式。
三种模式相互切换的图示如下:
notion image
  1. 【命令模式下】wq 指令 → 保存后退; 等同于快捷键 ZZ
    1. 在输入英文冒号进入命令模式后,输入 wq 表示保存并退出。
  1. 【命令模式下】q 指令 → 直接退;
    1. 在输入英文冒号进入命令模式后,在没有修改文本文件的情况下输入 q 可以退出,如果修改了文本文件,输入 q 会报错,提示你文本文件被修改,不会退出。
  1. 【命令模式下】q! 指令 → 强制退出; ↔ 等同于快捷键 ZQ
    1. 感叹号表示语气。在输入英文冒号进入命令模式后,输入 q! 表示强制退出,不会保存之前所有的操作。
  1. 【正常模式下】yy 指令 → 复制;
    1. 如果仅在键盘上输入 yy,表示复制当前行,再输入 p 后可以将复制的内容粘贴;
      如果在输入 yy 前输入数字 n,表示复制当前行至当前行往下的 n 行,如 5yy 表示复制当前行及当前行往下的 5 行。
  1. 【正常模式下】dd 指令 → 剪切;
    1. 与 yy 行类似,仅在键盘上输入 dd,表示剪切当前行(可以当删除键来用),再输入 p 后可以将剪切的内容粘贴;
      如果在输入 dd 前输入数字 n,表示剪切当前行至当前行往下的 n 行,如 5dd 表示剪切当前行及当前行往下的 5 行。
  1. 【正常模式下】/ 指令 → 查找;
    1. 在键盘上输入反斜杠 / 后,输入需要查找的字符即可进行定位,输入 n 即可跳转到下一个相同项。
  1. 【命令模式下】set nuset nonu → 是否显示行号;
    1. 在输入英文冒号进入命令模式后,set nu 表示显示文本文件内容的行号,set nonu 表示隐藏文本文件的行号。
  1. 正常模式下G, gg, shift+g → 跳转行号;
    1. 大写模式下的输入 G 就会跳转到文本文件末尾,输入小写gg 会跳转到文本文件的开头;
      如果在字母前面输入数字,比如 5G5gg 就会跳转到文本文件的对应行。
      对于 shift+g 指令,先输入数字,然后再按下 shift+g 键也可以实现跳转,如果直接输入 shift+g 会跳转到最后一行。
  1. 正常模式下u → 撤回上一步;

Vim 键盘图:
notion image
Linux 基础指令
用户管理类指令(增、删、改、查、分组)
【root 权限】用户的添加与删除、密码的更改
用户的添加操作和用户的删除操作均需要在 root 权限下进行,如果使用的是普通用户登录,建议先注销后再使用 root 用户登录,不建议在普通用户模式下输入 su - root 指令临时获取 root 权限操作。
用户的添加(useradd
用户的添加需要使用 useradd 用户名称 命令,比如我想要创建一个名称为 df01 的用户,可以使用 useradd df01
通过 useradd 用户名称 命令创建的用户目录默认存放在 /home 文件夹下。
如果我们希望将用户的目录添加到指定的名称中,我们可以使用这条指令 useradd -d 目录名称 用户名称 (其中 d 表示 directory),比如 useradd -d /home/test df01 ,这样就在 home 文件夹下创建了 test 文件夹用于存放用户 df01。
⚠️
注意,在 /home 目录下,虽然 mkdiruseradd 指令都创建了一个文件夹,但是前者创建的文件夹就只是个普通文件夹,无法进行登录等操作,没有用户权限;而后者却可以用于登录,具有用户权限。
用户的删除(userdel
  1. (工作中推荐方式)用户的删除需要使用 userdel 用户名称 命令,该命令会将用户的权限移除但是保留用户的目录文件夹;
  1. 删除用户也可以通过 userdel -r 用户名称 来操作,该命令不仅会将用户的权限移除,而且还会删除用户的目录文件夹(弹幕:“删库跑路”😅);
指定用户密码或修改密码(passwd
初始化新用户密码(即为新用户设置密码)或一个用户想要修改其他用户密码需要 root 权限;而修改自己的密码(已经初始化过),无需 root 权限。
通过passwd 用户名称 的方式可以为用户设置密码,比如 passwd tom
⚠️
注意,如果只输入 passwd 而没有输入用户名称,那么默认是为 root 用户修改密码。
默认修改 root 密码
默认修改 root 密码
如果不小心进入这个状态,可以通过 Ctrl+C 取消这个操作,在今后的很多进程中(Windows 或 Linux),都可以使用 Ctrl+C 取消某个进程,Ctrl+C 在命令行中基本是通用的。
用户切换与注销
  1. su - 用户名称 → 切换到某个账户;
    1. 如果使用的是 su - root 指令,系统会提示你输入密码,输入正确后即可临时使用 root 账户。root 账户与 Windows 的管理员账户一样,具有最高的权限,为了避免误操作,常常不会使用 root 登录系统。
      如果在 /home 目录下还有其他用户,如 jack,那么我们可以通过 su - jack 来切换到 jack 用户。
      从权限高的用户(如 root)切换到权限低的用户(如 普通用户), 不需要输入密码, 反之需要。
      🚧
      su root 指令与 su - root 指令的区别:
      su root 指令会继承当前用户的环境变量(不加载 root 的配置文件),在输入该指令后再输入 pwdprint working directory, 显示当前工作目录)会输出 /home/tom;同时,由于没有加载 root 用户的环境变量,会无法使用一些指令,比如 logout。(一般不建议使用该指令,后面会使用 sudo 指令来替代该指令)
      su - root 指令会加载 root 用户的环境变量,在输入该指令后再输入 pwd(显示当前工作目录)会输出 /home
  1. logout → 用户注销。
    1. 在 Xshell 中,当我们连接到 Linux 后,如果想要切换其他账户,可以使用 logout 指令先取消连接;如果我们此时处于临时使用 root 账户的状态,那么可以通过 logout 退回到普通用户的页面。
      🚧
      logout 注销指令在图形运行级别无效, 在运行级别 3 下有效。运行级别在后面的课程中会介绍。
用户信息的查询
如果我们想要查看任意用户的信息:
查询用户信息可以通过 id 用户名称 的方式来实现,如 id root ,如果用户不存在会返回无此用户。
如果能够成功返回信息,一般会有三个量 uid、gid、组。其中第一个是用户的 id,第二个是组的 id,第三个是用户所在的组(括号中)【后面会介绍组的含义】
notion image
如果我们想要查看最初登录系统的用户名称:
可以通过 whoami 指令或 who am i (信息更详细)指令 来查询。
【root 权限】组的管理与用户分组(Shell 的介绍、分组文件介绍)
为什么要进行分组?
Linux 的分组具有以下三个好处:
  1. 权限相同。组内的不同用户具有相同的系统权限;
  1. 方便管理。方便管理者为一些用户分配不同的权限,而不用一个个权限进行设置,更加方便;
  1. 文件共享。组内的不同用户可以共享组内的文件和设备。
groupadd 组名(创建组)
要将用户添加到一个组内,需要先创建一个组。通过 groupadd 组名 即可创建一个组。
groupdel 组名(删除组)
指令可以删除一个组。但需要注意的是,组内如果有用户存在,那么需要先将组内的所有用户移动到其他组,然后才会被允许删除,否则会报错。
useradd -g 组名 用户名(创建用户的同时对用户进行分组)
前面已经介绍过这个指令了,学习了分组后对这个指令进一步扩展。
通过前面介绍的 id 用户名 的方式即可查询用户所在的组是否有被修改。
usermod -g 组名 用户名(修改用户所在的组 ,保留目录修改权限(分组))
在创建用户的时候,如果没有为用户指定组,那么用户默认会分配到以用户名称命名的组内。
此时若想要为用户指定一个新的组,可以通过这条指令进行修改。
📌
为用户修改组后,如果要让用户拥有修改后组的权限,(Xshell 中)需要关闭当前终端后重新登录。
usermod -d 目标目录 用户名称 (修改用户主目录,保留权限(分组)修改目录)
这条指令用于修改用户登录时的初始目录,即 $Home 环境变量指向的路径(后面会学),默认不会将数据进行迁移,即原来的文件夹内容都还在。
如果目标目录不存在或是需要迁移旧数据,那么需要加上 -m 参数。
上面的代码理论上应该是正确的,但我在运行过程中总是会出现一些 “目录不存在”“usermod:无改变” 这样类似的问题,而且即便用了 -m 参数,数据似乎也没有迁移,很奇怪。
等学到后面以后再看看吧。
⚠️
在创建用户的时候如果不为用户指定组,那么用户默认会分配到以用户名称命名的组内。如 useradd jack 指令会创建一个用户,并将用户分配到 jack 组内。
什么是 Shell ?
Shell 就是用户和电脑之间的“翻译官”,由于电脑只会认识二进制指令(0 和 1 的序列),而在前面的课程中我们知道,用户不可能输入一系列二进制指令与电脑交流,而是输入类似于 lsgroupadd 这样的指令。
因此,我们需要利用 shell 帮助我们进行翻译,将我们日常使用的指令转换为电脑能够理解的二进制代码。
常用的 shell 主要有以下几种:
  • Bash(最常用,大多数 Linux 默认的 Shell)
  • Zsh(功能更强大,支持炫酷主题,很多人爱用)
  • Fish(对新手友好,能自动提示命令)
关于用户分组的几个文件介绍
/etc/passwd
etc 还记得吗,是 etcetera 的缩写,用于存放系统配置文件。其下的 passwd 顾名思义就是存放用户密码的文件夹。
每行的含义: 用户名:口令:用户标识号:组标识号:注释性描述:主目录:登录 Shell (了解即可)。
其中,口令指的是用户的密码,文件中会使用 x 表示。
/etc/shadow
这个文件夹用于存放口令的配置文件,上述 passwd 文件夹中的口令是在 shadow 中进行验证的。
每行的含义: 登录名:加密口令:最后一次修改时间:最小时间间隔:最大时间间隔:警告时间:不活动时间:失效时间:标志
在这个文件中,加密口令后面的内容都会使用特殊算法进行加密,无法直接查看,加密口令可以看到加密后的字符串。
notion image
这里有一个有趣的点,如果一个用户在创建的时候没有设置密码,那么加密口令这一栏会显示一个感叹号,如上面绿色箭头处。
/etc/group
Linux 组的配置文件,用于存放组的各种信息。
每行含义:组名:口令:组标识号:组内用户列表
其中,前面三个内容都可以在文件中看到,组内的用户列表是看不到的。
【root 权限】系统的关机与重启
主要使用到了以下这些指令:
  1. shutdown -h now (其中 h 表示 halt ,暂停的意思)→ 立即进行关机;
  1. shutdown -h n → 表示 Linux 系统将要在 n 分钟后关闭;
  1. shutdown -r now → 表示 Linux 系统将要进行重启;
  1. shutdown -r n → 表示 Linux 系统将要在 n 分钟后关闭;
  1. halt → 和第一条指令一样,立即执行关机;
  1. reboot → 和第三条指令一样,立即重新启动计算机;
  1. 【无需 root 权限】sync → 将存在内存的数据同步到磁盘中;
💡
韩老师建议:
不管是重启系统还是关闭系统, 首先要运行 sync 命令, 把内存中的数据写到磁盘中。虽然关机、重启的指令已经内置了 sync,但是建议还是在做这些操作前手动执行一下 sync。(小心使得万年船!😅)
运行级别(target
【root 权限】传统的运行级别(RunLevel)
运行级别
名称
终端指令
用途
0
Halt(停机)
init 0
关闭系统。与 shutdown -h nowhalt 指令效果相同。
1
Single-User
init 1
单用户模式(仅 root 权限,无网络,用于系统维护或找回丢失密码等情形)。
2
Multi-User
init 2
多用户模式(无图形界面和网络,部分服务不启动,一般不使用)。
3
Multi-User + Network
init 3
多用户模式(带网络服务,命令行界面,服务器常用)。
4
保留
init 4
未定义,用户可自定义。
5
Graphical
init 5
多用户模式 + 图形界面(如 GNOME、KDE,桌面版默认)。
6
Reboot(重启)
init 6
重启系统。与 shutdow -r nowreboot 指令效果相同。
传统的运行级别 0~6 是 SysVinit 的概念,只能死板的执行上面的这些指令,不能自定义组合功能,切换模式时要按顺序一个个启动服务,速度较慢。
传统的运行级别通过 init n 指令执行(视频中老师介绍的方式),如果我们想要切换到运行级别 3,可以在终端中输入 init 3.
【root 权限】现代的 target 指令
 target 是 systemd(现代 Linux 的系统管理工具)对传统运行级别(Runlevel)的升级和扩展。
target 指令不仅兼容了传统的运行级别,并且更加灵活,可以创建自己的 target,按需组合服务;同时,可以实现多个服务并行启动,加快系统初始化速度。
如何使用 target 实现传统的运行级别 0~6?
传统运行级别
systemd target
终端指令
说明
0(关机)
poweroff.target
systemctl poweroffsystemctl poweroff.target
关闭系统。
1(单用户)
rescue.target
systemctl rescuesystemctl isolate rescue.target
仅 root 权限,用于系统维护。
3(多用户命令行)
multi-user.target
systemctl isolate multi-user.target
带网络服务的命令行模式。
5(图形界面)
graphical.target
systemctl isolate graphical.target
图形界面模式(如 GNOME、KDE)。
6(重启)
reboot.target
systemctl rebootsystemctl isolate reboot.target
重启系统。
当然,在现代的 Linux 终端中,仍然可以使用 init n 命令,但系统内部仍会转换为上述终端指令执行。
常用的 target 指令介绍:
【无需 root 权限】systemctl get-default
查看当前的目标(target),即当前的运行级别。
systemctl set-default 名称.target
设置默认启动目标,即设置默认的运行级别。
systemctl set-default graphical.target 就会将运行环境默认设置为 图形界面。
‼️
注意,千万不要运行 systemctl set-default poweroff.targetsystemctl set-default reboot.target将运行环境设置为关机或重启状态,否则会陷入关机重启死循环中。
显示帮助文档(可选参数)
有两种方式可以显示指令的帮助文档,第一种是 help 指令,第二种是 man 指令。
  1. help 内置指令
    1. help 专门用于查看 Bash 或其他 Shell 内置命令 的帮助信息。如查看 cdechoaliasexithistory 等内置指令的帮助文档。
  1. man 外部指令
    1. man 是 manual 的缩写,用于查看 外部命令、系统调用、库函数 等的完整手册页(Manual Pages)。比如,man ls 命令就可以显示 ls 这个指令的帮助文档。
  1. 如何判断一个命令是内置命令还是外部命令呢?
    1. type 命令名称 可以帮助我们,在终端输入该命令回车后会直接显示某个命令是否是内置命令。比如,type cd 会返回结果“cd 是 shell 内嵌”。
💡
在进入帮助文档后,可以按下键盘上的 q 键返回命令行窗口。使用 man 指令显示的帮助文档可以使用 vim 编辑器那部分学过的快捷指令。
比如,如果想要快速查找内容,先输入反斜杠 / ,然后输入要查找的内容即可快速定位,按下键盘上的 n 即可跳转到下一个。
📌
帮助文档中,一行显示一个参数及其说明。
在参数前面如果有两条短横线 -- ,表示该参数为可选参数,短横线后面的为可选参数的全名(能够帮助我们理解和记忆参数);
如果有一条短横线 - ,短横线后面即为可选参数的别名(方便我们调用参数而不用写很长的参数名字);可选参数的全名和别名都可以调用参数
没有短横线的表示位置参数,是必须显示调用的。
ls 命令的帮助文档。其中黄色虚线框为可选参数别名,绿色虚线框为可选参数全名。
ls 命令的帮助文档。其中黄色虚线框为可选参数别名,绿色虚线框为可选参数全名。
在图中,如 --all 表是可选参数 all 的全名,-a 表示可选参数的别名,通过两种名字都可以调用可选参数;ls -als --all 是相同的,都是列出目录中的所有文件。
【补充】可选参数和位置参数 🌟🌟
看到弹幕中看到有很多人不清楚这两个参数之间的区别,老师也没有详细介绍,因此整理了一下供大家参考。
在指令与参数之间、参数与参数之间都需要使用空格进行分隔。
可选参数:
是指令的可选选项(options),通常以短横线(-)双短横线(--)开头。比如常见的-l-h--help 等。这些参数用来指定命令的不同功能或配置。
可选参数可以自由排列在命令后的任意位置(顺序无关紧要)
例如,ls -l 中的 -l 就是可选参数,用来显示详细信息。这里需要注意区分短选项(单个字母,如-a)和长选项(完整的单词,如--all)。
📌
注意,有些位置参数调用后是需要赋值的,有些位置参数调用只需要调用不需要赋值。
比如 ls -l 这个参数就是不需要赋值的,只要在 ls 指令后写上 -l 就表示调用可选参数;
usermod jack -g root (或 user -g root jack)指令中,-g 这个可选参数是需要赋值的,这条指令中赋的值为 root ,表示将用户 jack 移动到 root 分组中。
位置参数(positional arguments):
这些参数通常直接跟在命令后或在可选参数之后,通过位置顺序决定含义,因此位置参数间的先后顺序是非常重要的。
例如,在 usermod jack -g root 中,用户 jack 就是就是位置参数,指令用于将 jack 移动到 root 组中;而 -g 是可选参数。
如果我们对这条指令
📌
一般情况下,我个人推荐位置参数直接跟在指令后面,而可选参数放在位置参数后面,这样更加清晰。
如果对指令足够熟悉,那么将位置参数和可选参数混合摆放也没有问题。比如,usermod jack -g root 写为 user -g root jack
可选参数和位置参数对比:
特性
可选参数(Options)
位置参数(Arguments)
标识符
--- 开头
无特殊前缀
顺序影响
通常无关(部分命令例外)
严格依赖位置
作用
修改命令行为(如启用功能)
指定操作对象(如文件、目录)
是否必填
可选
可能必填(依命令而定)
带值方式
-o value--option=value
直接跟在命令或选项后
【补充】Linux 中的颜色高亮含义
颜色
含义
示例文件类型
蓝色
目录directory
/home/etc
白色
普通文件(文本、配置文件等)
file.txtconfig.conf
前面两个 .cfg 文件就是普通文件,后面 “公共~桌面” 就是目录文件
前面两个 .cfg 文件就是普通文件,后面 “公共~桌面” 就是目录文件
颜色
含义
示例文件类型
红色
压缩文件 或 损坏的符号链接
file.zipbroken_link
青色
符号链接symbolic link
/usr/bin/python -> python3.12
test_ln 就是符号链接,即快捷方式;test.zip 即为压缩文件
test_ln 就是符号链接,即快捷方式;test.zip 即为压缩文件
下面这些暂时未遇到,等遇到后再截图展示:
颜色
含义
示例文件类型
黄色
设备文件(如块设备、字符设备)
/dev/sda/dev/tty
粉红/紫色
图片文件 或 多媒体文件(依赖配置)
image.jpgvideo.mp4
绿色
可执行文件executable)或 脚本
./script.sh/usr/bin/ls
黑底黄字
管道文件FIFO
my_pipe
【补充】相对路径和绝对路径
路径有两种表示方法:绝对路径相对路径
  1. 绝对路径指的是以根目录开始的路径,根目录使用反斜杠 / 表示。如 /home 就表示根目录下的 home 文件夹,/root 表示根目录下的 root 文件夹。
  1. 相对路径指的是相对当前目录的路径(当前目录可以通过 pwd 指令显示),用于方便寻找当前文件夹下的路径。比如此时我们当前所在目录为 /home,通过 ls 指令显示当前目录下有 tom 文件夹,我们已知 tom 文件夹中有一个 test 文件夹,那么我们就可以通过相对路径 tom/test 来表示该文件夹的位置【如果使用绝对路径表示那就是 /home/tom/test】。
  1. 在 Linux 系统中,. 表示的是当前目录,.. 表示的是上一级目录。
    1. 比如我们现在在 /home 目录下,我们可以通过 ./tom/test 的方式来表示相对路径,cd ./tom/testcd tom/test 两种方式都能够将终端目录切换到 test 文件夹。
      如果我们此时想要回到上一级目录,我们可以通过 cd .. 的方式来实现。
      现在假设有这样一个情形,在 /home 文件夹下有两个用户文件夹 tomjack ,我们现在在 tom 文件夹下,那么我们就可以通过 cd ../jack 来实现切换。
  1. 路径的末尾加上反斜杠 / 表示该文件是目录(即文件夹),不加反斜杠表示是普通文件。如 /home/test/ 表示目录,/home/test.txt 表示文件。
    1. 不过一般情况下区分的也不是那么严格。目录末尾亦可以不加上反斜杠,因为文件夹与文件如果在同一目录下是不能同名的,同理,文件末尾也可以加上反斜杠。但规范中的写法是目录末尾加上反斜杠,文件不加,知道有这么个细节就行。
文件目录操作类指令(文件的创建、内容的输出等)
本部分仅介绍指令的常用方法,要了解更多方法请查看帮助文档。
这里的很多指令不一定都会是未来工作中使用频率最高的,但一定要在脑中有这些指令的印象,不记得怎么用不要紧,要知道有指令可以方便我们实现哪些功能。
ls 指令(打印输出目录结构)
ls → list files.
💡
在 Linux 的目录结构中,如果文件名是以 . 开头的,比如 .local 表示这个文件夹是一个隐藏文件,使用 ls 命令无法查看。
如果要查看某个目录下的所有文件和文件夹,可以通过 ls -a 指令来查看,其中 aall 的缩写。
ls -a
表示显示当前目录下的所有文件。
ls -lll
ll 指令可以简化表示 ls -l 指令。用于将当前目录下的可见文件以每个文件一行的方式显示(会显示文件的详细信息,如文件所有者、文件大小等)。
ls -al
表示将当前目录下的所有文件以每个文件一行的方式显示。
ls 路径
对指定路径进行显示文件的操作,如当前在 /root 目录下,想要查看 /home/test 文件夹下的内容,就可以使用ls /home/test
ls 路径 [指令]
路径可以和前面介绍的几个指令结合起来使用,如 ls /home -al/home 目录下的所有文件以每个文件一行的方式显示。
ls -h
h 参数表示 human-readable ,意思是人类可读,用于将机器友好的输出(如字节、秒数等)转换为更直观的单位(如 KB/MB/GB、分钟/小时等)
-h 参数通常与 -l 参数搭配起来使用,仅使用 -h 参数无法显示转换效果(因为此时仅输出有哪些文件,不会输出详细信息)。
常用方法为: ls -hlls -ahl ,与 -h-a 参数搭配使用 。
💡
ls 指令之间顺序可以打乱,且指令可以组合使用。比如 ls -al /home 指令与 ls /home -al 是相同的。
cd 指令(绝对路径和相对路径)
cd 指令的含义是 change directory,利用该指令,我们可以方便切换终端当前所在的目录位置,之后在终端中使用的指令会默认对该目录发挥作用;
cd 指令的使用方法在前面已经简单介绍过了,就是 cd 路径
cd ..
返回上一级目录。
cd ~ (中间有空格):
返回根目录。
mkdir 指令(创建文件夹)
mkdir 是 make directory 的缩写,意思是创建文件夹。
mkdir 的使用语法如下: mkdir 路径 ,其中的路径既可以使用绝对路径,也可以使用相对路径。
mkdir jack 即可在当前目录下创建一个名为 jack 的文件夹,mkdir /home/Lily 即可在 home 文件夹下创建一个名为 Lily 的文件夹。
mkdir 默认只能够在已存在的目录下创建新的文件夹,如果想要在不存在的目录下创建一个文件夹(一次性创建多级目录),如 mkdir /home/test/jack01 ,其中 test 文件夹并不存在,那么指令会报错。
如果想要实现创建多级目录的功能,可以使用 mkdir -p /home/test/jack01-p 为可选参数,是 parents (父目录)的缩写。
💡
如果想要查看 mkdir 的更多指令,可以通过 man mkdir 来进行查询。
rmdir 指令(移除空文件夹)
rmdirremove directory 的缩写.
rmdir 指令可以用于移除指定的空文件夹,用法为 rmdir 路径
rm\rm 指令(移除某个文件或文件夹)
rmremove 的缩写。
rm 指令用于移除特定的一个或多个文件,使用方法为 rm 文件路径1 文件路径2... ,输入指令并回车后会提示是否需要删除某个或多个文件。
如果不希望系统提示,直接删除某个文件,那么可以使用 \rm 文件路径 的方法直接删除,也可以使用 rm -f 文件路径 的方式删除。
rm\rm 指令一般不能用于移除某个目录(文件夹),但如果指定了 -r 参数,那么就可以删除目录(文件夹),如 rm -r /home/test,如果不希望系统提示,可以使用 rm -rf 目录路径
💡
总之,rm 既可以用来删除文件,也可以用于删除文件夹。
touch 指令(创建空文件)
用于创建一个空文件,与 vim 不同,vim 创建了一个文件后,会直接进入该文件(选择编辑或退出),而 touch 不会进入。
touch 的使用方法为 touch 路径 ,路径可以为绝对和相对,比如 touch a.txt 就是在当前目录下创建一个名为 a.txt 的文件; touch /home/tom/b.txt 就是利用绝对路径在 /home/tom/ 目录下创建一个名为 b.txt 的文件。
需要注意的是,touch 指向路径的文件夹必须存在,然后才能在路径下创建空文件(比如前面指令中 /home/tom 必须存在才能创建 b.txt 的文件)。

💡
创建空文件还有一个方法,> 路径 ,比如 > a.txt> /home/tom/b.txt ,关于 > 在后面会学到。
cp 指令(复制文件或文件夹)
cpcopy 的缩写。用于拷贝文件到指定的目录,具体的用法为 cp 文件路径 目标路径 ,即将文件复制到目标路径下
比如,加入现在在 /home 文件夹下,可以使用 cp /home/test/test.txt test2/ 将 test.txt 文件进行复制,指令中目标路径末尾是否有反斜杠 / 都可以。
如果我们想要移动某个文件夹到某个路径下,那么可以使用 cp -r 文件夹路径 目标路径 指令,可选参数(即加上短斜杠的参数)顺序无所谓,cp 文件夹路径 目标路径 -rcp -r 文件夹路径 目标路径 两条指令是一样的【但是位置参数,即文件夹路径和目标路径的顺序不能颠倒】。
\cp 指令(复制并覆盖文件)
当我们想要让某个文件夹覆盖另一个文件夹时,如果使用 cp 指令,会提示我们是否进行覆盖,而 \cp 指令不会提示直接进行强制覆盖
在需要覆盖的文件比较少,或者是否覆盖文件需要我们确认时,可以使用 cp 指令,但如果有大量文件需要覆盖且不需要我们进行确认,那么就需要用到 \cp 指令了。
\cp 指令的使用方法与 cp 指令一致,只是效果不同。
\cp 指令的示例如: \cp /home/test /home/test2 ,即用 test 文件夹覆盖 test2 文件夹。
mv 指令(重命名、移动(剪切) 文件或文件夹)
该指令的帮助文档中描述为 改“源文件”名到“目标文件”名,或移动“源文件”(可以不只一个)到另一个“目录”
使用方法为: mv 源文件路径 目标路径
也就是说,mv 指令有两个主要的用途
  1. 对文件或文件夹进行重命名操作;
  1. 剪切文件或文件夹到另一个位置。
mv 的用法示例如下:
  1. 重命名。假设现在在 /home 目录下,且目录中有 testtest2 两个文件夹,使用mv test test2 指令时,如果 test是文件夹,那么就会对该文件夹重命名,如果 test 是文件,那么就会对文件进行重命名(也可以对后缀名进行修改)。
  1. 剪切(移动)文件。比如现在在 /home 目录下,mv test/test.txt test2/test.txt 会将 test 文件夹中的 test.txt 文件移动到 test2 文件夹下。
  1. 剪切并重命名文件。还是使用 2 的例子,mv test/test.txt test2/hello.txt 就会实现剪切并重命名的功能。
💡
这里有一个注意点,在使用类似 mv test test2 这个命令时,如果 test2 并不在当前目录下,那么会将 test 重命名为 test2;如果 test2 在当前目录下,则会将 test 文件夹移动到 test2 文件夹中。
more 指令(文件以分页形式输出)
more 指令在帮助文档中的描述为:在显示器上阅读文件的过滤器
通常,我们可以通过 more 指令将指定文件内容输出并分页显示,配合上一些快捷键阅读起来很方便。
more 指令的使用方法为: more 指定路径 ,如 more /etc/profile
使用 more 指令输出指定的文件后,可以使用以下快捷键:
操作
描述
空格
向下翻一页
Enter
向下翻一行
q
立即离开 more,不再显示文件内容
Ctrl+F
向下滚动一屏
Ctrl+B
返回上一屏
=
输出当前行的行号
:f
输出文件名和当前行的行号
less 指令(文件以分页形式输出,功能更强大)
less 指令与 more 指令类似,但比起 more 指令来说功能更加强大,适用于读取大文件。
less 指令的官方描述如下:
Less 是一个类似于 more 的程序,但它允许在文件中向前和向后移动。 此外,Less 在启动前无需读取整个输入文件,因此在输入文件较大的情况下,它的启动速度比 vi 等文本编辑器更快。 Less 使用 termcap(或某些系统上的 terminfo),因此可以在各种终端上运行。
less 的使用方法为: less 指定路径 ,如 less /etc/profile
less常用快捷键操作如下:
快捷键
描述
空格
向下翻一页
/字符串
向下寻找输入的字符串,按下 n 表示向下寻找,按下 N 表示向上寻找。
?字符串
向上寻找输入的字符串,按下 n 表示向上寻找,按下 N 表示向下寻找。
q
离开 less
『pagedown』
向下翻动一页
『pageup』
向上翻动一页
测试用的样例文本:
cat 指令(文件全文输出)
catconcatenate 单词的缩写,意思是”连接”。
基础用法
cat 指令在帮助文档中的描述为:连接文件并在标准输出上输出
cat 指令可以让我们以只读的方式查看文件,避免误操作将文件修改保存。
cat 指令的用法为: cat 文件路径 ,如果想要显示文件的行号,那么可以使用 cat 文件路径 -n
使用示例: cat /etc/profile -n 就可以将 profile 文件的内容输出并显示行号。
与管道指令和 more 配合
管道指令指的是将两个指令拼接在一起,指令间通过 | 分隔,用于对 | 符号前指令的结果进行 | 后指令的操作。
比如,cat /etc/profile -n | more 就可以对 cat /etc/profile -n 的结果执行 more 指令,将文件内容分页展示。
echo 指令(输出单行指令)
echo 在英文中是“回声”的意思,将输入的内容输出到命令行类似于是回声的过程。
echo 指令用于在终端中显示一行文本,用法为 echo [选项] [输出内容]
一般,echo 可以用于输出环境变量或搭配 >>> 指令(后面会介绍)发挥作用。
使用示例如下:
输出环境路径: echo $PATH
输出主机名:echo $HOSTNAME
输出内容到终端:echo "Hello World!"
🌟 >>> 指令(覆盖或追加输出内容到文件)
这两个命令似乎无法通过 manhelp 查看其帮助文档。
> 指令用于将输出的内容重定向到指定的文件中,用人话说就是会将输出的内容覆盖指定文件中的内容;
>> 指令用于将输出的内容追加到指定的文件中,所谓的追加就是不覆盖原文件内容,在内容底部加上原来要输出的内容。
使用示例:
  1. ls 指令搭配使用;
    1. 在前面的学习中我们知道,ls 指令可以将当前目录下的所有文件名称输出,既然是输出,那么我们就可以使用 > 指令将输出的内容追加到某个文件(若文件不存在,则系统会先创建后再追加)中。
      ls >> /home/ls.txt
  1. cat 指令搭配使用;
    1. cat 可以将某个文件的内容输出到终端,因此可以利用这个特性将某个文件的内容追加或覆盖到另一个文件中,如 cat /home/ls.txt >> /home/hello.txt 即可将 ls.txt 中的内容追加到 hello.txt 中。
  1. 🌟 > 路径
    1. 这条指令可以实现两个功能: ① 创建空文件(当指定路径不存在时); ② 清空某个文件的内容(当文件存在时)。
      利用 > 路径 创建一个空文件产生的效果与 touch 路径 一致。比如, > /home/a.txt 即可在 /home 目录下创建一个名为 a.txt 的空文件。
常用的搭配:
  1. ls -l > 文件 → 将当前目录下可见文件的名称以行的形式覆盖另一个文件的内容;
  1. ls -al >> 文件 → 将当前目录下所有文件的名称以行的形式追加从到另一个文件中;
  1. cat 文件1 > 文件2 → 将文件 1 中的内容覆盖到文件 2 中;
  1. echo "内容" >> 文件 → 将某行内容追加到文件中(echo 只能输出一行内容)。
head 指令(只显示文件的前几行)
head 指令用于输出文件的开头部分,默认输出文件开头的 10 行内容。
head 的用法为: head [选项] [文件路径] 。如 head 杂文.txt 即可显示 杂文.txt 文件中的前 10 行内容。
如果我们想要自定义能够查看的行数,可以通过 -n 参数来调整,如 head 杂文.txt -5 即可显示 杂文.txt 文件中的前 5 行内容。
tail 指令(只显示文件末尾的几行)
tail 指令与 tail 指令十分类似,tail 指令用于输出文件的结尾部分,默认输出文件结尾的 10 行内容。
tail 的用法为: tail [选项] [文件路径] 。如 tail 杂文.txt 即可显示 杂文.txt 文件中的最后 10 行内容。
其他常用可选参数:
-n
如果我们想要自定义能够查看的行数,可以通过 -n 参数来调整,如 tail 杂文.txt -5 即可显示 杂文.txt 文件中的最后 5 行的内容。
-f
follow 的缩写,意思是打开文件后不立即退出,可以看到实时更新的内容。
比如,假如我们在 /home/hello.txt 文件中的内容为 hello world ,那么如果我们通过 tail -f /home/hello.txt 的方式打开文件,文件不会立即退出,此时我们打开 Xshell 或 终端,输入指令 echo "hello world" >> /home/hello.txt ,那么就可以看到 tail 中实时更新的内容。
🧐
不过不知道为什么,我使用 vim 编辑器编辑后内容不会更新。
ln 指令(创建快捷方式【符号链接】)
TLDRln 指令的官方描述
在 Unix 世界里有两个'link'(连接)概念,一般称之为硬连接软连接
一个硬连接仅仅是一个文件名。(一个文件可以有好几个文件名,只有将最后一个文件名从磁盘上删除,才能把这个文件删掉。文件名的个数是由 ls(1) 来确定的。所有的文件名都处于同一个状态,也就没有什么“源名字”之说。通常文件系统里的一个文件的所有名字包含着一样的数据信息,不过这样也不是必需的。)
一个软连接(或符号连接)是完全不同的:它是一个包含了路径信息的小小的指定文件。因此,软连接可以指向不同文件系统里的文件(比如由NFS装载的不同机器文件系统上的文件),甚至可以指向一个不一定确实存在的文件。在软连接文件被访问(系统调用 open(2) 或 stat(2))的时候,操作系统用该文件所包含的路径替换该文件的访问介入点,从而实现对所指文件的访问。(用命令 rm(1) 和 unlink(2) 可以删除连接,但不是删除该文件所指向的文件。系统指定调用 lstat(2) 和readlink(2)来读取连接文件与其所指文件的状态。到底是对软连接文件操作,还是对被指向文件操作,由于不同操作系统件存在不同的系统调用,而存在着差异。)
ln 在文件间产生连接。缺省时,产生硬连接,有 -s 选项,则产生符号(软)连接。如果仅仅只给出一个文件名,那么 ln 将在当前目录里产生这个文件的连接, 也就是说,以该文件(的最后一个)名称等同的名字在当前目录里产生一个连接 (GNU范围内); 如果最后一个参数是一个已存在的目录名, ln 将在那个目录里给每一个源文件用以与源文件相同的文件名产生连接,(不同情况见以下--no-dereference的描述);如果只给出两个文件名,ln 将产生源文件的连接; 如果最后一个参数不是一个目录名或多于两个文件名,则报错。缺省时,ln 不删除已存在的文件或符号连接。 (因此,它可以被用来锁定目标文件,即当dest已经不存在时) 但选项-f可以强制执行。在已存在的实现中,只有超级用户才能建立目录的硬连接。POSIX 禁止系统调用link(2)和ln建立目录的硬连接(但是允许在不同的文件系统间建立硬连接)。
ln 指令简单的说就是类似于 Windows 系统中创建一个快捷方式。
ln 指令的使用方法为: ln -s [源文件或目录] [目标目录/软链接名称] ,如 ln -s /root /home/myroot 指令为 root 目录创建了一个软连接 myroot
创建了软连接后,如果使用 cd 软连接路径 进入软连接目录,那么在该目录下进行的一切操作都会在 源目录 下同步。如果此时使用 pwd 打印当前目录,显示的是软连接的存放目录。删除软连接本身并不会对源文件或目录造成影响。
📌
进入存放有软连接的目录时,比如 /home 目录下存放着 myroot 软连接,如果使用 ll 指令按行显示目录结构,表示软连接的字符串会以 “l” 开头(如下图所示)。
notion image
history 指令(查询历史指令)
用于显示曾经执行过的历史指令,直接输入 history 即可执行。
如果想要显示最近 n 条指令,那么就输入 history n ,如 history 10 ,显示最近 10 条指令。
如果想要调用某个具体编号下的指令,那么就输入 !n 表示执行编号为 n 的指令,如 !387 就可以执行编号为 387 的指令(编号在 history指令输出的结果中会显示)。不过有一个小注意点,!n 指令本身不会显示在指令列表中,不然不就容易陷入死循环了嘛😅。
【补充】命令连接符的介绍(|&&||
本部分主要介绍管道指令、&&||
管道指令 |:将前一个命令的 标准输出(stdout) 作为后一个命令的 标准输入(stdin)。通常用于数据流的处理。
&& :只有 前一个命令成功执行(退出状态码为 0),才会执行后一个命令。比如, ll /home && cd /home 先列出 /home 目录的文件,然后再进入 /home 中。
|| :只有 前一个命令执行失败(退出状态码非 0),才会执行后一个命令。通常用于错误处理或回退操作,可结合 && 使用。
日期时间类指令
下面所介绍的指令执行后都会在命令行中输出结果,这也意味着我们可以使用文件目录类指令中介绍的 >>> 指令将输出内容直接写入文件中。
在生成文档日志的时候,可以利用这个特性在日志中加入时间。
输出日期时间
显示完整日期:
在终端中直接输入 date 即可显示当前的系统日期,时间,星期等。
只显示年份(大写):
在终端中输入 date "+%Y[自定义内容]" 即可打印输出今年年份,注意,空格、双引号、+% 都不能够省略,自定义内容可以随意填写,Y 要大写。
如,输入 date "+%Y 年" 就会输出 2025 年
只显示月份(小写):
在终端中输入 date "+%m[自定义内容]" 即可打印输出今年的月份,与显示年份的注意事项一样。
如,输入 date "+%m 月" 就会输出 3 月
只显示日期(小写):
在终端中输入 date "+%d[自定义内容]" 即可打印输出今天的日期,与显示年份的注意事项一样。
时分秒的显示(大写):
通过上面三个示例,我们可以发现,想要单独显示哪个内容只需要将 % 后面的字母更换即可,因此如果想要单独输出时、分、秒,可以将 % 的内容分别写为 %H%M%S 。三个字母都需要大写。
组合使用:
组合使用时,这些符号之间没有规定需要使用什么字符来连接,因此可以写为这样,date "+%Y%m%d%H%M%S" 。但很明显,这样输出后是不利于我们辨别的。
因此,我们至少会在这些符号中间加上一个空格(也可以是其他分隔符),如 date "+%Y %m %d %H %M %S" ,或 date "+%Y 年 %m 月 %d 日 %H 点 %M 分 %S 秒"
更改日期时间
更改日期:
可以通过 date -s 年月日指令实现,但是无法只修改年或只修改月和日,只能三者同时修改,年月日之间可以直接相连,也可以使用分隔符(短横线 -)相连。
如果直接相连,那么年份必须 4 位,月份必须 2 位,日必须 2 位,总共要有 8 位;
若使用短横线 - 连接,年份可以 1~4 位,月份和日期可以只有 1 位,否则会报错。
📌
注意,无论使用哪种连接,都必须采用 年-月-日 的顺序,否则系统可能会误判。
使用示例如下:
  1. date -s 20220302
  1. date -s 2025-03-20
更改时间:
更改时间可以通过 date -s H:M:S 来进行修改,它们也是只能同时修改,时间使用英文冒号 : 分隔。
使用示例:
  1. date -s 3:12:20
  1. date -s 15:20:33
 
输出日历
显示当前月份日期:
通过 cal 指令即可输出今年今月的日历,同时,对于今天的日期还会使用方框框起来(如果写入文件中,方框会消失)。
显示指定年份日期:
使用 cal 年份 即可实现。
显示当前年份日期:
通过 cal -y 即可输出当前年份日期,注意如果你前面更改过日期时间,那么日历也会发生相应变化。
将星期一设置为一周的第一天:
cal 指令默认将周日设置为一周的第一天,如果要显示以星期一为第一天的日历,那么需要使用 cal -m 指令。
有趣的日历——历史上曾经消失的 10 天
notion image
文件查找类指令
find 指令(全盘/局部搜索文件)
find 指令是在硬盘中查找文件所在位置,能够将从指定目录向下递归遍历各个子目录, 将满足条件的文件或者目录显示在终端。
find 的使用方法为: find 待查询路径 查找方式

  • 如果不添加查找方式,直接使用 find 文件路径 命令,执行后会在当前目录下查找名为 test 的目录或文件,并递归搜索其内部内容(隐藏文件和可见文件都会输出)。如 find *.txt 可以将当前目录下所有后缀名为 txt 的文件,其中 * 表示任意字符(后面会学)。
findls 指令输出结果比较
find 文件路径ls -a 文件路径 两个指令相似,都会列出路径下所有文件,但显示的效果还是有些不同的(可以通过图片自己体会一下):
notion image

  • 如果添加查找方式,常用的有以下三种:
      1. 文件名查找;
        1. 通过 find 待查询路径 -name 文件名 的方式可以查找路径下的文件,如果不存在会输出无该文件。
      1. 用户名查找;
        1. 通过 find 待查询路径 -user 用户名 的方式可以查找在某个路径下指定用户配置相关的所有文件,如 find /home -user jack
      1. 文件大小查找;
        1. 通过 find 待查询路径 -size 文件大小 的方式可以查找路径下符合大小要求的所有文件,其中文件大小选项可以只输入数字,表示查找指定字节大小的文件;
          如果我们希望查找大于某个阈值或小于某个阈值的文件,可以分别搭配符号 +- 来实现,如果对单位有要求(默认是字节为单位),那么可以分别使用 k,M,G 表示 千字节兆字节吉字节
          比如,find /home -size +200M 是寻找 /home 目录下 200 M 以上的文件,find /home -size -2G 是寻找 /home 目录下 2 G 以下的文件。
      📌
      注意,如果想要全盘查询,那么待查询路径就只写一个反斜杠 / 即可,如 find / -size +10G 表示全盘搜索文件大小大于 10 G 的文件。
      如果仅想在当前目录下查询,路径可以省略。如果当前就在根目录下,省略与加上反斜杠是一样的。
      💡
      如果想要中断查询的进程,可以输入 Ctrl+C
locate 指令(数据库搜索文件,更快)
locate 指令可以快速定位需要查找的文件,不过我们需要提前创建或更新一个数据库给 locate ,否则无法查找。
locate 指令的使用方法很简单,locate 文件路径 即可进行查找了。但在这之前,我们必须先使用 updatedb 指令(db 表示 database,数据库)来创建或更新一个数据库(第一次使用就是创建)。
which 指令(查询“指令”位置)
该指令可以定位我们所使用的指令在 Linux 中的存放位置,使用方法为 which 指令名称
grep 指令(过滤文件内容并输出)🌟🌟
grep 是 Global Regular Expression Print 的缩写,意思是通过正则表达式(Regular Expression)全局(Global)搜索文本内容,并打印(Print)匹配的行
grep 指令的使用方法为: grep [选项] 查找内容 文件路径 。比如,/home 目录下有一个 hello.txt 文件(文件内容如下),我想要返回所有 yes 所在行,就可以使用 grep yes /home/hello.txt
如果有对过滤的结果有特定需求,可以在选项中加入可选参数:
  1. -n 参数,用于显示匹配行的行号;比如 grep yes /home/hello.txt -n
  1. -i 参数,用于忽略字母大小写。比如 grep yes /home/hello.txt -i
上述两个参数也可以组合起来使用,如 grep yes /home/hello.txt -in
  1. -v 参数,用于反向匹配。比如 ll 可以输出三项内容 a.txt , b.txt , c.txt ,如果使用 grep -v "a" ,则输出结果只有 b.txt , c.txt ;而如果使用 grep "a" ,输出结果为 a.txt

grep 参数与 cat 参数的结合使用:
我们可以将 cat 输出的结果通过管道命令送给 grep 进行操作,比如
压缩与解压缩类指令
为什么要进行压缩操作?
压缩文件或文件夹的好处在于可以节省存储空间,提升文件传输效率。对于文本文件(如日志、代码)而言,通常可压缩到原大小的 10%-30%。
压缩的使用场景主要有两个:
① 需要传输文件时,压缩能够减小文件体积,传输更快;
② 对于不常使用但又需要保留的文件,通过压缩可以节省空间,需要时解压即可。
这里特别说明一下单文件压缩,在实际应用中,服务日志(如 Nginx、应用日志)每天可能生成数 GB 数据;MySQL 处理后的数据导出后也会有很大的体积,因此往往都需要进行压缩。
gzip/gunzip 指令(压缩单文件,高压缩率)
gzip 中的 g 表示 GNU 项目开发,zip 就是压缩的意思。gunzip 不是 “gun + zip” 而是 “g + unzip” ,表示使用 GNU 项目进行解压缩。
单文件压缩/解压使用 gzip/gunzip 指令(主要用于 Unix/Linux 系统中),使用方式很简单,gzip 待压缩文件路径1 待压缩文件路径2...gunzip 待解压文件路径(gz 结尾)1 待解压文件路径2...默认是压缩和解压到当前目录下,压缩后后缀为 .gz
比如,gzip /home/杂文.txt

如果希望压缩文件到指定目录中,可以通过下面的方式:
  • 结合 可选参数 -c> 指令来完成,如 gzip /home/杂文.txt -c > /home/test/杂文.txt.gz
    • -c (可能是 C 语言中 cout 的缩写)表示 将压缩结果输出到标准输出(不删除原文件);注意不要直接使用 gzip 杂文.txt -c 这个指令,会输出一堆乱码。
      【这个过程也可以同时更改解压缩后文件的名字,如 gzip /home/杂文.txt -c > /home/test/a.txt.gz 】。

如果希望解压缩文件到指定目录中,可以通过下面的方式:
  • 结合 可选参数 -c> 指令来完成,如 gunzip /home/test/杂文.txt.gz -c > /home/a.txt

💡
上面压缩和解压缩的操作都可以多次重复执行,因为原文件都会保留。
zip/unzip 指令(压缩文件夹,中等压缩率)
该指令压缩的后缀为 .zip
zip/unzip 用于对文件夹解压缩,支持指定目标路径

压缩:
  • 对于压缩而言,可以使用 zip -r 目标路径(.zip 结尾) 原文件路径 的方式进行(r 是 recursive 的缩写,表示递归),且必须要写目标路径,目标路径必须以 zip 文件结尾,否则无法压缩成功。
    • 使用示例: zip -r test.zip testzip -r /home/test.zip /home/test
📌
如果不加上 -r ,即使压缩成功了,解压后里面也没有任何文件。

解压缩:
  • 对于解压缩而言,可以使用 unzip 压缩文件路径(.zip 结尾) 的方式将文件解压到当前目录,如果要加上目标路径,需要使用可选参数 -d 指定(d 是 directory 的缩写,表示目录)。
    • 使用示例:unzip test.zip 【解压到当前目录下】或 unzip -d /root /home/test.zip 【解压到指定路径】。
🌟 tar 指令(归档压缩操作,Linux 偏爱的解压缩指令)
tar 通常用于备份 Linux 系统的文件。
【官方描述】TLDR
tar 程序用于储存或展开 tar 存档文件。存档文件可放在磁盘中,也可以存为普通文件。
tar 是需要参数的,可选的参数是 A、c、d、r、t、u、x。
您在使用 tar 时必须首先为 tar 指定至少一个参数;然后,您必须指定要处理的文件或目录
如果指定一个目录,则该目录下的所有子目录都将被加入存档。
简单来说,tar 指令主要用于将多个文件或目录打包成一个归档文件(默认不压缩),或是进行压缩与解压。
tar 指令的使用方法为 tar [选项] [文件名] [文件或目录列表路径] ,常用选项如下:
选项
全称
作用
-c
create(创建)
创建归档文件(.tar)
-x
extract(提取)
解包/解压归档文件
-v
verbose(冗长的,啰嗦的)
显示操作过程(可选)
-f
file
指定归档文件名(必须放在最后
-z
gzip
使用 gzip 压缩/解压(生成 .tar.gz)
-t
list
查看归档内容(不解压)
-C
Change directory
解压到指定目录(不与上面的命令合并使用),如 -cxvCf 是错误的,只能单独使用
常用命令:
为什么 Linux 程序员更偏爱于使用 tar 指令?
  1. 首先,tar 指令在使用后能够保留完整保留权限、时间戳、符号链接等;
  1. 其次,符合 Linux 哲学, 完美契合“小工具协作”的理念,可与 sshgzip 等工具通过管道(|)协作;
  1. 最后,灵活性高,可以按需选择压缩算法。
文件管理类指令(文件所有者、所在组更改;文件权限管理)
修改文件所有者和所在组
基本概念
对于一个文件而言,有所有者所在组其他组三个概念。
谁创建了文件,谁就是文件的所有者
创建文件的用户是属于哪个组的,那么文件的所在组就是哪个组;
其他的组相对于文件的所在组就是其他组
查看文件所有者和文件所在的组(ls
通过 ls -l 操作就可以查看文件的所在组了,ls -al 的方式可以显示所有文件的所在组。
notion image
上图中,红框部分所显示的就是文件所有者;绿框部分所显示的为文件所在组。
【root 权限】文件所有者的更改(chown
修改文件的所有者不会更改文件的所在组。chownchange owner 的缩写。
只更改文件或目录所有者
chown 所有者名称 文件名称 ,其中 “所有者名称” 表示要将文件所有者更改为哪个所有者
比如,a.txt 文件的所有者是 root, chown zzdf a.txt 可以将它的所有者更改为 zzdf。
可选参数 -c (显示修改过程)
notion image
递归更改目录本身及其子目录的所有者(chown -R
Linux 严格区分大小写,因此这里的可选参数 -R 只能使用大写的 R。
notion image
如上图所示,orange 目录及其子目录、子文件的所有者都更改为了 jack
文件所在组的更改(chgrp
修改文件所在组同样不会对文件所有者进行更改。chgrpchange group 的缩写。
只更改文件或目录本身的所在组(chgrp
使用 chgrp 即可进行文件所在组的更改,指令的使用方法为: chgrp [组名] [文件名] ,比如
可选参数 -c (显示修改过程)
notion image
递归更改目录本身及其子目录的所在组(chgrp -R
Linux 严格区分大小写,因此这里的可选参数 -R 只能使用大写的 R。
notion image
从上图中可以看到移动的整个过程,除了 orange 目录本身以外,其下的子文件、子目录也发生了组的更改。
【root 权限】权限查看、管理
🌟🌟 文件目录的读、写、执行权限的详细介绍
针对普通文件的权限:
权限
符号
含义
示例场景
读(r)
r
允许查看文件内容(如读取文本、查看二进制文件内容)
使用 cat file.txtless file.log 查看文件内容
写(w)
w
允许修改文件内容(如编辑文本、追加数据、清空文件)
使用 vim file.txt 编辑文件,或 echo "text" >> file.txt 追加内容
执行(x)
x
允许将文件作为程序执行(如运行脚本、二进制可执行文件)
运行 ./script.sh 或 /usr/bin/ls(需文件本身是可执行格式)
针对目录的权限:
权限
符号
含义
示例场景
读(r)
r
允许列出目录中的文件名(如查看目录包含哪些文件)
使用 ls /home 列出目录内容(但无法访问文件内容)
写(w)
w
允许在目录中创建、删除或重命名文件(需同时有执行权限)
使用 touch newfile 创建文件,或 rm oldfile 删除文件
执行(x)
x
允许进入目录并访问其内容(如 cd 进入目录或访问子文件元数据)
能使用 cd /home 进入目录并访问文件内容, 但无法通过 ls 指令查看目录下的文件名和目录名。
文件详细信息解读(权限查看)
在 Linux 终端中输入 ls -l (或 ll)就可以查看每个文件的详细信息了,包括文件的权限。
从输出的结果中选取一条文件详细信息进行查看:
drwxr-xr-x. 2 jack root 4096 3月 23 10:58 fruit
上面的这条记录中,我将各个部分都使用了不同的颜色进行了高亮。
文件的类型(橙色,第 1 个
第一个橙色的字母表示文件的类型,共有 5 种类型 —— d, -, l, c, b
d 表示的是目录,应该是 directory 的缩写;
- 表示的是普通文件,如 .txt 文件, .tar 压缩文件等;
l 表示的是链接文件(快捷方式),通常在最后会有箭头指向原文件,比如:
notion image
c 表示的是字符设备,如鼠标、键盘等;
什么是字符设备?
字符设备是一种以字节流(字符)为单位进行数据传输的硬件或虚拟设备。它通过逐字符(或逐字节)的方式与系统交互,适合需要实时性顺序访问的场景。
常见的字符设备:
设备类型
示例
物理设备
键盘(/dev/input/event*)、鼠标、串口(/dev/ttyS0)、终端(/dev/tty)。
虚拟设备
空设备(/dev/null)、随机数生成器(/dev/urandom)。
特殊功能设备
音频设备(/dev/snd/*)、打印机(/dev/lp0)。
字符设备与块设备的区别:
对比维度
字符设备
块设备
数据传输单位
字符/字节(如逐字节读取键盘输入)。
固定大小的块(如硬盘一次读写 4KB 数据块)。
访问方式
顺序访问(不支持直接跳转到指定位置)。
支持随机访问(可直接跳转到任意块读写数据)。
缓存机制
通常无缓存(直接读写硬件)。
有缓存(通过页缓存或块缓存提升性能)。
典型设备
键盘、鼠标、串口、终端。
硬盘(/dev/sda)、SSD、U盘、CD-ROM。
b 表示的是块设备,如硬盘。
对于上面举例的语句,第一个字符为 d,表示 fruit 是一个目录(文件夹)。
文件所有者权限(绿色,第 2~4 个
文件所有者权限通过三个字符来描述 —— r, w, x
r 表示的是所有者对文件具有 读权限
w 表示的是所有者对文件具有 写权限
x 表示的是所有者对文件具有 执行权限
它们三者的顺序是固定的,如果有哪个权限就标上位置对应的字母(比如有写权限就在第 3 个字符位置标上 w),没有哪个权限就标上短横线 -
对于上面举例的语句,表示的是文件所有者 jack 对文件 fruit 具有读、写和执行权限。
文件所在组中其他用户权限(蓝色,第 5~7 个
当一个组中的用户 jack 创建了文件后,与 jack 同组的其他用户对该文件具有的权限。
与所有者权限的描述一样,都是使用 r, w, x 三个字符来描述,有哪个权限就标上位置对应的字母,没有哪个权限就标上短横线 -
对于上面举例的语句,同组其他用户对文件 fruit 具有读和执行权限,没有写权限。
文件其他组用户权限(紫色,第 8~10 个
当一个组中的用户 jack 创建了文件后,与 jack 不同组的其他用户对该文件具有的权限。
查看方式与文件所在组中其他用户权限的描述相同。
目录包含子文件与子目录个数(粉色,第 11 个字符
如果查看的是文件的详细信息,那么这个数字就是 1;
如果查看的是目录的详细信息,那么这个数字就是该目录下所拥有的文件及目录的总数;
对于上面举例的语句,文件 fruit 表示一个目录,目录中含有的文件及目录总数为 2。
文件的所有者和所在组
这个在前面已经介绍过了,这里再说明一下:
数字后面的遇到的第一个字符串就是文件的所有者;
数字后面遇到的第二个字符串就是文件的所在组。
对于上面举例的语句,文件的所有者就是 jack ,文件的所在组就是 root 组。
文件或目录的大小
上面这条语句中的 4096 就表示文件的大小为 4096 字节(B);
当然,在文件大小大于 1024 字节的时候,我们更希望使用人性化的表示方式,因此使用指令 ll -h 来查看文件,选择同一条文件详细信息进行查看:
drwxr-xr-x. 2 jack root 4.0K 3月 23 10:58 fruit
4.0K 表示的就是 4 千字节(1 千字节为 1024 字节);
同样地,M(或 MB) 表示的是 兆字节(1024 千字节),G (或 GB)表示吉字节(1024 兆字节)
编辑时间
在文件名前面的一段日期表示的就是文件的最后编辑时间。
对于上面举例的语句,文件的最后编辑时间就是 3月 23 10:58
修改文件或目录权限(chmod
修改文件或目录的权限可以通过 chmod 指令(应该是 change mode 的缩写)来完成。
chmod 的使用方法为: chmod 变更后权限 文件或目录 ,比如 chmod a=rwx,g-w,o-rw fruit (后面会介绍具体含义)。
📌
使用该指令时千万注意,不要增加多余的空格
变更后的权限 这一项中,如果是对多个操作对象进行变更操作,一定不要加上没用的空格(别问我是怎么知道的😣,比如 chmod a=rwx, g-w, o-rw fruit (在逗号后面加空格)或 chmod a = rwx fruit(在等号周围加空格),在写完每一项后加空格是程序员惯有的操作,但有时候也会害了我们。
操作对象表示(u, g, o, a
在修改权限时,我们可以对所有者、所在组以及其他组的权限进行修改;
既然有三个操作对象,那么我们就需要用三个符号来分别表示它们:
u 是 user 的缩写,指代的是所有者;
g 是 group 的缩写,指代的是所在组;
o 是 others 的缩写,指代的是其他组;
a 是 all 的缩写,指代的是所有者、所在组和其他组一起。
第一种变更权限的方式 —— 符号(+, -, =)【增量变更】
优点是可以单独修改某个操作对象的权限,缺点是需要写比较多的内容。
通过 r, w, x, - 四个符号来代指权限(顺序可以不固定),比如 rwx 表示有读、写和执行权限,rw- 表示的是有读、写权限,无执行权限。
+
加号表示的是为某个操作对象增加某个或某些权限,比如 chmod o+rw fruit,赋予 fruit 目录的其他组用户读和写权限;
-
减号表示的是为某个操作对象移除某个或某些权限,比如 chmod o-rw fruit,移除 fruit 目录的其他组用户读和写权限;
=
等号表示的是直接为某个操作对象赋予某些权限,比如 chmod o=rw fruit,赋予 fruit 目录的其他组用户读和写权限,但没有执行权限。
📌
上述三种符号可以混合使用,比如 chmod a=rwx,g-w,o-rw fruit
第二种变更权限的方式 —— 数字【覆盖变更】
优点是写起来简洁优雅,但是无法灵活设置所有者、所在组和其他组的权限。
这种变更权限的方式可以结合二进制数字来理解和记忆,这样会非常简单。
📌
rwx 三位按顺序对应二进制数字 111 的高低位,然后将二进制数转换为八进制数(直接理解为 10 进制也没问题)表示即可。
r 是最高位,值为 4;w 是中间位,值为 2;x 是最低位,值为 1;(如果不知道什么是八进制数,记住权限对应的值就行,最后相加)
当二进制对应位为 1 时表示赋予该权限,当二进制对应位为 0 时表示不赋予该权限。
一一对应关系
000--- (无读、写、执行权限);
001--x (无读、写权限,有执行权限);
010-w- (无读、执行权限,有写权限);
011-wx (无读权限,有写、执行权限);
100r-- (无写、执行权限,有读权限);
101r-x (无写权限,有读、执行权限);
110rw- (无执行权限,有读、写权限);
111rwx (有读、写、执行权限);
举个简单的例子,如果仅赋予 读和写 的权限,那么二进制表示就是 110,值为 6;如果仅赋予 读和执行 的权限,那么二进制表示就是 101,值为 5。

具体的使用方法为,chmod 数字 文件或目录
📌
从上面三个示例中可以看出,chmod 一般需要同时设置三个组的权限(否则文件所有者无权限),因此没有符号法灵活。
定时任务类指令
周期性任务
Linux 通过 crond 服务来执行定时任务(或周期性任务),比如定时清理某些文件、开机自动执行某个脚本等。
crond 服务核心组件
组件
作用
crond 服务
后台守护进程,负责读取配置并执行任务。crond 意思是“周期任务”。
crontab 配置
提交周期性任务。crontab 是 crond table 的缩写,意思是周期任务表。
日志记录
任务执行日志(如 /var/log/cron
📌
后面我们主要通过编辑 crontab 文件中的内容来安排定时任务。
crontab 指令介绍(-e-i-r
crontab 指令默认是为当前用户分配周期任务,文件的存储路径为 /var/spool/cron/用户名
crontab 主要有三种工作模式: 编辑查询删除
crontab -e
执行指令后进入 crontab 文件,在文件的每一行输入指令即可周期性进行调用。
crontab -i
这条语句用于查询当前用户 crontab 配置文件中的所有指令。
crontab -r
这条语句用于删除当前用户的 crontab 配置文件。

【root 权限】crontab 指令更改其他用户的指令(修改自身的指令无需 root 权限):
📌
需要注意的是,想要使用 crontab 修改其他用户的指令必须要具有 root 权限。不建议直接修改 /var/spool/cron/用户名 文件来修改指令配置。
crontab 指令使用方法
首先通过 crontab -e 指令打开当前用户的定时任务编辑页面,页面的操作方法与 vim 编辑器一致,按下 i 后开始编辑。
编辑页面中,指令书写需遵循的规则
  1. 指令的基本写法为: 分钟 小时 日 月 星期 用户 可执行脚本路径或指令
    1. 其中,可执行脚本的路径应该为绝对路径。可以为指定用户添加某条指令,需要有 root 权限(为当前用户添加无需 root 权限)。
  1. 每一行表示一条独立的任务指令,如果一条指令无法在一行内完成,可以在末尾加上反斜杠 \ 进行换行;
    1. 可以加入注释,注释以 # 开头,可以单独一行,也可以跟在命令后;
      1. 指令中的 分钟、小时、日、月、星期 都被称为是一段,每一段内不能够添加空格(只能以逗号分隔),段与段之间以空格分隔。
        时间(分钟、小时、日、月、星期)的表示
        这里推荐大家一个 网站 ,这个网站中输入 crontab 指令即可翻译成对应的时间,但对你的英语有一点挑战(翻译软件翻译不准确),大家也可以自行上网搜索 cronta 指令校验工具。emmm,或者干脆问 AI 算了😶‍🌫️
        指令中时间设置的顺序为: 分钟 小时 日 月 星期
        下面以 0-30/2 3,5 * 2 1-5 ls -l /home/ > /home/list.txt 这条指令为例进行说明。
        基础符号
        符号
        含义
        *
        表示任意时间,比如每一分钟或每一小时、每一天等等。 上述指令中 * 的位置与 “” 对应,表示每一天。
        ,
        英文逗号指定多个离散值,逗号间不能有空格。 上述指令中 3,5 的位置与小时对应,表示 3 点和 5 点两个时间点。
        -
        短横线用于指定连续的区间,短横线两侧不能有空格。 上述指令中 0-30/2 与分钟对应,其中的 0-30 表示 0 分到 30 分。 指令中 1-5 与星期对应,表示星期一到星期五。
        */n
        正斜杠 /n 表示每 n 个时间点执行一次,两侧不能有空格*/n 表示在任意时间点中每隔 n 个时间点执行一次 上述指令中 0-30/2 中的 /2 表示每隔 2 分钟,合起来表示 0 分到 30 分间每隔 2 分钟执行一次。
        📌
        注意,*/1 和单个 * 的意义相同,表示每个时间点,*/5 就是每 5 个时间点,如每 5 分钟(0 5 10…)。
        将上面的解释联合起来,0-30/2 3,5 * 2 1-5 就表示定时的时间点需要满足:
        ① 0-30 分钟间且每隔两分钟,即 0 2 4 6…;
        ② 3 点 和 5 点两个时间点;
        ③ 每一天;
        ④ 2 月;
        ⑤ 星期一到星期五;
        也就是说,每年 2 月的星期一到星期五的 3 点到 3 点半,5 点到 5 点半间每隔两分钟执行一次😅(不知道现实中会不会这么复杂)。
        大家可以尝试一下 * */2 3,5 */2 * 这个时间如何判断呢?【答案: 每年 1, 3, 5, 7, 9, 11 月的 3 号和 5 号每两小时的每一分钟执行(如果有些迷糊就记住条件间需要满足逻辑与的关系)】
        📌
        指定多个离散值,逗号间不能有空格。需要说明的是,时间的设置中,分钟、小时、日、月、星期无论怎么样设置,最终都是以逻辑与的方式结合的。也就是说,只有满足所有条件的时间点才会执行指令
        特殊符号
        关键字
        等效表达式
        含义
        @reboot
        系统启动时执行一次(不保证任务只执行一次,需自行处理)。
        @yearly
        0 0 1 1 *
        每年1月1日0:00执行。
        @annually
        同 @yearly
        同上。
        @monthly
        0 0 1 * *
        每月1日0:00执行。
        @weekly
        0 0 * * 0
        每周日0:00执行。
        @daily
        0 0 * * *
        每天0:00执行。
        @midnight
        同 @daily
        同上。
        @hourly
        0 * * * *
        每小时0分执行(每整点执行)。
        使用示例如下:
        星期的表示方法
        星期除了可以使用数字 0~7 表示以外(0 和 7 都表示星期日),也可以使用星期的单词和简称表示。
        星期名称
        英文全称
        简称
        示例用法(cron 表达式)
        星期一
        Monday
        Mon
        0 8 * * Mon(每周一 8:00 执行)
        星期二
        Tuesday
        Tue
        0 0 * * Tue(每周二 0:00 执行)
        星期三
        Wednesday
        Wed
        30 12 * * Wed(每周三 12:30 执行)
        星期四
        Thursday
        Thu
        0 18 * * Thu(每周四 18:00 执行)
        星期五
        Friday
        Fri
        0 9 * * Fri(每周五 9:00 执行)
        星期六
        Saturday
        Sat
        0 0 * * Sat(每周六 0:00 执行)
        星期日
        Sunday
        Sun
        0 0 * * Sun(每周日 0:00 执行)
        使用 crontab 执行脚本
        一次性任务
        Linux 通过 at 指令来执行一次性任务,例如在某个时刻重启服务、发送提醒或运行脚本。
        at 指令核心组件
        组件
        作用
        atd 服务
        负责在后台监听任务队列,并在指定时间触发任务执行。atd 是 AT Daemon 的英文缩写,意思是 “AT 守护进程”。
        atd 配置
        提交一次性任务,指定执行时间及相关操作。
        at 指令介绍
        at 指令用于在 指定时间执行一次性任务,指令序列由 atd 进程来调控。
        atd 会每隔 60 秒查看一次指令队列,检查是否有指令的定时时间满足要求,如果有,则运行该指令,且运行完成后将该指令移除。
        如果有多条指令处于同一时间下,会按照指令添加的先后顺序执行。
        📌
        在使用 at 指令的时候,一定要确保 atd 进程是启动的,可以通过 ps -ef 查看当前 Linux 内部的进程,通过 ps -ef | grep atd 来筛选出含有 atd 指令的进程。如果能够筛选到,说明 atd 进程是开启的(如下图所示)。
        notion image
        at 指令使用方法
        在终端中输入 at [选项] 时间 即可设置指令的定时时间,同时进入指令添加页面,在页面中输入要执行的指令或是脚本(如 shell 脚本(.sh))后,通过 Ctrl+D 保存任务,再按下 Ctrl+D 退出页面(也就是说一共要按下两次 Ctrl+D)。

        at 指令中时间的设置
        Linux 中 at 指令设置时间的方式非常灵活,基本上你按照正常的思维表示时间都不会出错。
        1. hh:mm 。默认设置的是当天的时间,如 11:30 ,如果时间已经过了,则顺延到明天。
          1. hh:mm 默认采用的是 24 小时制,如下午 1 点 30 分为 13:30 ;但也可以手动采用 12 小时制,即 am 和 pm 表示时间,如下午 1 点 30 分为 1:30pm
        1. 12 小时制整点定时。
          1. 与方式一类似,但在整点运行时可以不使用分钟,比如 1pm12pm 等。(注意,12 am 表示的是凌晨 0 点,12 pm 才是正午)。
        1. 使用具体日期来表示。
          1. 使用具体日期而没有指定时间默认指的是指定日期的凌晨 0 点开始。
            具体日期的表示方法
            格式
            示例
            说明
            YYYY-[M]M-DD
            2025-03-272025-3-27
            ISO 标准格式(推荐使用)
            MM/DD/[YY]YY
            03/27/2025 或 3/27/25
            月/日/年(需用 / 分隔)
            DD.MM.[YY]YY
            27.03.202527.03.25
            日.月.年(需用 . 分隔)
            Month DD [YYYY]
            March 27 2025 或 Mar 27
            月份名称(全称或缩写)
            12 个月的英文简称
            ​月份
            ​英文全称
            ​简称
            一月
            January
            Jan
            二月
            February
            Feb
            三月
            March
            Mar
            四月
            April
            Apr
            五月
            May
            May
            六月
            June
            Jun
            七月
            July
            Jul
            八月
            August
            Aug
            九月
            September
            Sep
            十月
            October
            Oct
            十一月
            November
            Nov
            十二月
            December
            Dec
        1. 使用相对时间来表示(at now + <数量> <时间单位>)。
          1. now 后面的加号不能省略,now 后面的内容间可以加上空格,也可以不加上空格,比如 now + 5 minutesnow+5minutes 都可以。
            可用的时间单位
            单位
            全称
            示例
            分钟
            minutes
            now + 5 minutes
            小时
            hours
            now + 2 hours
            days
            now + 3 days
            weeks
            now + 1 week
            months
            now + 6 months(部分系统支持)
        1. 关键字时间的使用。
          1. 关键字时间有三个: midnight00:00 (24 小时制),noon12:00 (24 小时制),teatime16:00。三个的意思分别是 午夜,正午,下午茶。
        1. 关键字日期的使用。
          1. 日期关键字
            关键词
            含义
            示例
            tomorrow
            明天凌晨 0:00
            at 14:30 tomorrow(明天 14:30)
            today
            今天
            at 23:59 today(今天 23:59)
            next <星期名称>
            下一个指定的星期几,星期可以使用简称
            next Monday(下周一)
            next week
            下周的同一时间点(7 天后)
            at 09:00 next week(7 天后 09:00)
            星期的全称和简称
            星期名称
            英文全称
            简称
            星期一
            Monday
            Mon
            星期二
            Tuesday
            Tue
            星期三
            Wednesday
            Wed
            星期四
            Thursday
            Thu
            星期五
            Friday
            Fri
            星期六
            Saturday
            Sat
            星期日
            Sunday
            Sun
            💡
            经试验,上述全称和简称都可以使用,而且大小写都是可以识别的,比如 at MON ,甚至是 at WEdat SaT 这样都可以。可以自己尝试一下。
            📌
            注意,如果使用 today 关键字且没有指定具体时间(即 at today),表示的含义是立刻执行
        1. 时间日期混合使用。
          1. 可以采用 at 时间 日期 的方式进行定时,其中时间和日期的表示方式与前面介绍的方式相同。
            这里请注意,时间日期混合使用时,指定的时间不能是过去的时间或日期,否则会报错:refusing to create job destined in the past
            示例
        at 指令中选项的设置
        选项
        含义
        -m
        当指定的任务开始执行后,无论任务是否有输出,都将给用户发送邮件。
        -l
        等价于指令 atq 。用于列出当前用户所有待执行的任务及任务 id
        -d 任务id
        等价于 atrm 。用于删除指定任务,比如 at -d 34 为删除第 34 条待执行的指令
        -c 任务id
        显示指定任务 id 的详细内容。
        -q 队列
        表示使用指定的队列。
        -f 文件
        从指定文件(.sh 文件)中读取要执行的命令。
        -t 时间戳
        通过 Unix 时间戳(秒级)指定执行时间。(不知道怎么用😅)
        可以自行测试一下,at now+2minutes -m ; echo "hello" >> /home/over.txt ,任务结束后输出 “您在 /var/spool/mail/root 中有新邮件”。
        【补充】文件信息统计
        wc 指令
        wc 指令是 Word Count 的缩写,直译为“字数统计”,但其功能不仅限于统计单词,还扩展到了统计文件的基本信息。
        功能/选项
        作用
        示例
        wc 文件
        默认同时输出 行数、单词数、字节数
        wc data.txt → 3 12 60 data.txt
        -l(line)
        仅统计 行数
        wc -l logs.txt → 150 logs.txt
        -w(word)
        仅统计 单词数
        wc -w essay.txt → 850 essay.txt
        -c(character)
        仅统计 字节数
        wc -c image.jpg → 409600 image.jpg
        -m
        统计 字符数(兼容多字节字符)
        wc -m text.txt → 2000 text.txt
        wc 指令常常用于与管道指令搭配,比如
        提取路径前后缀指令
        这部分指令是在 shell 编程部分介绍的,但我觉得放在这个部分可能更加合适,不难,但也可以在学习 shell 编程时返回来看。
        提取文件名/目录名(提取路径后缀)
        主要使用 basename 指令,该指令是用于 从文件路径中提取文件名或目录名 的实用工具。
        使用方法: basename 文件路径 [后缀]
        • 其中文件路径为需要提取文件名或目录名的路径,后缀为可选参数,若指定了后缀(如 .txt),则进一步去除文件名中的后缀。
        • 直接提取路径中的最后一个 / 后的内容(如果最后一个 / 后面没有内容,则提取倒数第二个 / 后面的内容),比如 basename /home/tom/ 返回的结果为 tom
        提取前缀名
        主要使用 dirname 指令,用于 从文件路径中提取目录部分 的命令,与 basename(提取文件名)互补,常用于脚本中处理路径或文件定位。
        使用方法: dir 文件路径 。比如 dirname /home/tom/hello.txt 返回的结果是 /home/tom
        Linux 硬盘相关
        🌟 新增硬盘并实现分区挂载
        分区和挂载的简单理解
        在 Linux 系统中,分区(Partition) 是将物理硬盘划分为多个逻辑存储单元的过程。每个分区可以独立管理、格式化和挂载,用于存储文件或实现特定功能(如交换空间)。
        由于 Linux 中万物皆目录,因此 Linux 的分区需要使用 Linux 的文件系统来表示的。当我们在 Linux 中添加硬盘并分区后,需要将硬盘挂载到 Linux 文件系统中。这样,当我们对文件目录进行操作时,物理硬盘中也会进行相应的变化,比如添加文件。
        一般,物理硬盘需要经过 分区 → 格式化 → 挂载 的逻辑操作,才能整合到 Linux 文件系统中,其中挂载是连接物理存储和逻辑目录树的核心步骤,使分区内容可通过目录访问。
        通过老师的这幅图也能够比较好理解:
        notion image
        Linux 硬盘说明
        Linux 中的硬盘主要有 IDE 硬盘(Integrated Drive Electronics,即集成驱动器电子设备)和 SCSI 硬盘(Small Computer System Interface,即小型计算机系统接口)两种,IDE 是早期个人电脑的主流接口,目前主要使用的是 SCSI 硬盘。
        IDE 驱动器标识符(了解即可)
        IDE 的驱动器标识符为 hdx~ ,需要分为三个部分来看。
        • 第一部分为 ”hd”,表示该标识符为 IDE 驱动器标识符;
        • 第二部分为 “x”,表示的是盘号。x 是一个泛指,可以取 a, b, c, d 这四个值。
          • a 表示基本盘,是第一个 IDE 通道的主设备(Primary Master);
          • b 表示基本从属盘,是第一个 IDE 通道的从设备(Primary Slave);
          • c 表示辅助主盘,是第二个 IDE 通道的主设备(Secondary Master);
          • d 表示辅助从属盘,是第二个 IDE 通道的从设备(Secondary Slave)。
        • 第三部分为 “~”,表示的是分区。~ 也是一个泛指,取值为数字。
          • 1~4 表示的是主分区或扩展分区;
          • 5 开始往后是逻辑分区

        比如,hda1 表示的是 IDE 基本盘的分区 1hdd4 表示的是 IDE 辅助从属盘的分区 4.
        SCSI 硬盘标识符
        SCSI 硬盘标识符使用 sdx~ 表示,需要分为三个部分来看。
        • 第一个部分为 “sd ”,表示该标识符为 SCSI 硬盘标识符;
        • 第二个部分为 “x”,表示的是盘号。只不过与 IDE 不同,不限于 a, b, c, d 四个取值。规则如下:
          • 按检测顺序分配:字母从 a 开始,根据系统检测到设备的顺序递增。
          • 无物理通道限制:支持任意数量设备(理论上可达 sdz 甚至更多,取决于控制器能力)。
          • 无主从关系:SCSI 设备通过唯一 ID 识别,无需主/从跳线配置。
        • 第三个部分为 ”~”,表示的是分区。~ 也是一个泛指,取值为数字。
          • 1~4 表示的是主分区或扩展分区;
          • 5 开始往后是逻辑分区

        比如,sda1 表示的是 SCSI 硬盘 a 的分区 1。
        lsblklsblk -f 指令
        lsblk 是 list block devices 的缩写。
        用于列出所有块设备,查看所有设备的挂载情况。
        在终端中输入 lsblk 指令后,输出结果中各项的含义(下面左侧部分为输出的代码,右侧为各列的含义说明):
         
        列名
        说明
        NAME
        设备名称(如 sda 表示第一块硬盘,sda1 表示其第一个分区)。
        MAJ:MIN
        设备的主设备号(Major)和次设备号(Minor),用于内核识别设备(见下文示例)。
        RM
        是否为可移动设备(Removable)。1 表示可移动(如 U 盘),0 表示固定设备。
        SIZE
        设备或分区的总容量(如 20G 表示 20GB)。
        RO
        是否为只读设备(Read-Only)。1 表示只读(如光盘),0 表示可读写。
        TYPE
        设备类型。disk:物理硬盘;part:分区;rom:光盘等。
        MOUNTPOINT
        分区的挂载点(如 / 表示根分区,/boot 表示启动分区,空表示未挂载)。
        在终端中输入 lsblk -f 指令后,输出结果中的各项含义(下面左侧部分为输出的代码,右侧为各列的含义说明):
        列名
        说明
        NAME
        设备名称(如 sda1 表示第一块硬盘的第一个分区)。
        FSTYPE
        文件系统类型(如 ext4xfsswapvfat,未格式化则为空)。
        LABEL
        文件系统的卷标(用户自定义的标识符,如 BOOTDATA)。
        UUID
        文件系统的唯一标识符(Universally Unique Identifier),用于可靠识别设备。
        MOUNTPOINT
        分区的挂载路径(如 / 表示根目录,[SWAP] 表示交换分区)。
        如何增加一块新硬盘并实现挂载
        在进行新硬盘挂载前,建议大家保存一份快照,以免后续操作错误时无法恢复。
        具体的步骤如下:
        1. 虚拟机添加新硬盘;
        1. 磁盘分区;
        1. 格式化硬盘(分区内创建文件系统);
        1. 挂载(将硬盘分区系统链接到 Linux 文件系统);
        1. (设置自动挂载)。
        💡
        看到弹幕中有很多人因为增加了新硬盘导致 vmware 或 centos 需要重装,但我按照老师的步骤来是没有出错的。因此建议大家先看完老师的操作后再按照笔记中的步骤来。出错的原因也有可能是系统问题,我是在 windows vmware 虚拟机下操作的,没有问题,可能其它系统会有其他细节。
        添加新磁盘的步骤(图片)
        notion image
        notion image
        notion image
        notion image
        notion image
        📌
        添加完新磁盘后,需要重启虚拟机,在终端中输入 reboot 即可重启。重启后在终端中输入lsblk 即可查看到刚刚创建的磁盘 sdb ,但磁盘中还没有进行分区。
        (磁盘默认是添加到 /dev/ 目录下的,过去曾经介绍过,/dev/ 用于存放磁盘目录)
        磁盘分区
        在终端中输入 fdisk /dev/sdb 指令后,输入 m ,即可进入到磁盘修改页面,在这个页面中可以对磁盘进行分区。
        在这个页面中,有以下这些指令可供选择(页面中是英文的):
        m
        显示命令列表
        p
        显示磁盘分区 同 fdisk –l
        n
        新增分区
        d
        删除分区
        w
        写入并退出
        q
        不写入直接退出
        我们需要输入 n 新增一个分区,然后输入 p 选择分区类型为主分区,之后就一直按下回车,保持默认设置即可。
        在最后又会回到先前显示指令的页面中,按下 w 即可保存并退出(如果输入 q 会不保存直接退出)。
        格式化硬盘
        在终端中输入指令 mkfs -t ext4 /dev/sdb1 即可将硬盘格式化为 ext4 文件系统。其中 mkfs 是 "make file system" 的缩写,直译为 “创建文件系统”。它的作用是将一个分区或存储设备格式化为特定的文件系统(如 ext4、XFS、swap 等),使其能够被操作系统读写和管理。
        ext4XFSswap 三个文件系统的含义:
        • 常规用途ext4(稳定性好,适合个人/服务器)。
        • 大文件/高并发XFS(性能更优,支持日志恢复)。
        • 交换空间swap(需通过 mkswap 和 swapon 激活)

         
        挂载/取消挂载
        挂载是将分区与 Linux 文件系统中的文件目录联系起来,因此我们需要现有一个可供挂载的目录。一般是在根目录下创建一个文件目录进行挂载。
        挂载使用的指令是 mount 分区路径 挂载目录 。比如 mount /dev/sdb1 /newdisk ,其中 sdb1 就是我们先前创建的分区,这条指令的意思是将 sdb1 这个分区挂载到 /newdisk 目录下,也就是将物理磁盘和文件目录关联。
        如果要取消挂载,可以使用 umonut 挂载目录umount 分区路径 指令,如 umount /newdiskumount /dev/sdb1
        📌
        挂载与取消挂载时需要注意,我们手动挂载的目录默认是只在本次运行期间有效,重启系统后原来挂载的指令会失效。
        如果想要在重启后,保持先前磁盘分区的挂载状态,需要进行自动挂载的设置;
        同理,如果我们通过自动挂载将目录与磁盘分区绑定了,取消挂载的指令也只在本次运行期间有效,重启后失效。
        自动挂载
        要实现自动挂载需要我们手动操作 /etc/fstab 文件,具体的过程如下:
        1. vim /etc/fstab 打开有关挂载的配置文件;
          1. 文件中各列的含义
            notion image
            列数
            字段
            含义
            示例解析
            第 1 列
            文件系统标识
            设备路径(如 /dev/sdb1)或分区的 UUID
            使用设备名 /dev/sdb1(建议改用 UUID,避免设备名变化导致挂载失败)。
            第 2 列
            挂载点
            文件系统挂载到的目录(必须是已存在的空目录)。
            挂载到 /newdisk 目录。
            第 3 列
            文件系统类型
            分区的文件系统类型(如 ext4xfsswap)。
            分区格式化为 ext4 文件系统。
            第 4 列
            挂载选项
            挂载时使用的选项(多个选项用逗号分隔)。
            defaults 表示默认选项:rw,suid,dev,exec,auto,nouser,async
            第 5 列
            dump 备份标志
            0 表示永远不纳入 dump -w/-W (后面备份部分会介绍)的检查。 >0(如 1、7、30):表示“当上次备份时间距今 ≥ 该值天数时,才算『备份过期』,需要补做一次备份”
            0 表示不备份此分区。 1 表示每天检查一次备份
            第 6 列
            fsck 检查顺序
            系统启动时检查文件系统的顺序(0 表示不检查,根分区通常设为 1)。
            0 表示不检查此分区(非系统关键数据盘可设为 0,根分区建议设为 1)。
        1. 按照前面学习的 vim 编辑器的使用方法,将光标移动到第一行 UUID,键盘按下 yy 复制该行,然后再按下 p 在该行上方粘贴;
        1. 然后将该行的 UUID=… 一列替换为新分区的名称 /dev/sdb1 ,将挂载路径更改为 /newdisk ,将最后两列数字改为 0 后,esc 退出编辑,输入 冒号 :wq 保存退出。
          1. 当然,也可以通过 lsblk -f 指令查看新添加的磁盘分区的 UUID,将其复制后作为第一列的值。
        notion image

        完成上面的编辑操作后,在终端中继续输入 mount -a 即可立刻生效更改(或者也可以通过 reboot 指令重启后生效)。
        查询系统磁盘占用情况(df
        df 是 disk free(磁盘空闲)的英文缩写,用于查看文件系统的 可用磁盘空间 和整体磁盘使用情况,包括已用、剩余空间及挂载点信息。
        通常使用 df -h 指令查询系统整体磁盘的使用情况。其中 -h 参数表示磁盘容量以可读方式展现(默认使用字节呈现)。
        下图是我的虚拟机中使用 df -h 指令的输出结果:
        notion image
        查询指定目录占用情况(du
        du 是 disk usage(磁盘使用量)的英文缩写,用于统计 文件或目录 在磁盘中的实际占用空间,支持递归计算子目录的累积大小。
        du [目录] -h 指令即可查询指定目录的磁盘占用情况(占用内存大小),-h 参数用于将输出结果以可读形式展现(默认是以字节形式呈现)。
        其中 目录 选项可以不写,如果不写表示的含义就是查询当前目录下的磁盘占用情况。
        其他常用参数:
        参数
        全称
        含义
        -a
        --all
        显示对所有文件的统计,而不只是包含子目录。
        -s
        --summarize
        指定目录占用大小汇总。du -s 表示当前目录占用空间的大小。
        --max-depth=n
        --max-depth=n
        只输出小于等于第 n 层的目录的总计。 --max-depth=0 的作用同于 -s 选项。
        -c
        --total
        列出明细的同时,在最后一行输出汇总值。
        --max-depth=n 参数的输出结果:
        notion image
        以树状图形式输出目录结构
        需要先安装 tree 这个库。通过 yum install tree 指令安装。使用 yum 指令需要 root 权限。
        如果在终端中直接输入 yum install tree 指令,大概率是会报错的(据说是 2024年6月30日后CentOS 7 的官方仓库已经停止使用了),因此我们需要事先配置一个镜像仓库。
        直接将下方的代码复制到终端中(如果询问是否多行粘贴,点击“是”):
        运行后即可将 yum 指令的镜像仓库配置为 阿里云。接着再使用 yum install tree 指令即可成功安装 tree 库。

        测试: 在终端中输入 tree 指令后,默认会显示当前目录的树状图结构:
        notion image
        如果需要指定目录,则使用 tree 目录路径 即可。
        硬盘实用指令
        在介绍实用指令之前,需要先介绍两个指令:
        • grep "^-" ,其中 grep 我们已经学过了,是条件过滤器。而后面引号部分中的 ^- 是正则表达式,表示将开头为短横线 - 的输出结果筛选出来。^ 后面的字符可以替换为其他的,比如 ^d 表示开头为字母 d 的,^l 表示开头为 l 的。
        • wc 指令大家可以使用 man wc 查看一下它的帮助文档,文档中说 wc 指令用于输出文件中的行数、单词数、字节数
          • l, --lines 可以输出换行符统计数。
          • w, --words 可以输出单词统计数。

        1. 统计 /opt 目录下子文件的个数。
          1. ls -l /opt | grep "^-" | wc -l ,将 /opt 目录下的文件以行的形式全部列出来,然后过滤出开头为短横线 - 的行(即筛选出子文件),再对这些行的数量进行统计输出。
        1. 统计 /opt 目录下子目录的个数。
          1. ls -l /opt | grep "^d" | wc -l 。将 /opt 目录下的文件以行的形式全部列出来,然后过滤出开头为 d 的行(即筛选出子目录),再对这些行的数量进行统计输出。
        1. 统计 /opt 目录下文件的个数,包括子目录中的。
          1. ls -lR /opt | grep "^d" | wc -l 。其中 R 参数表示递归列出 /opt 目录中子目录下的文件。
        1. 统计 /opt 目录下子目录的个数,包括子目录中的子目录。
          1. ls -lR /opt | grep "^d" | wc -l
        Linux 网络配置相关
        什么是 VMnet1 和 VMnet8
        VMnet1 实际上就是仅主机模式,VMnet8 实际上就是 NAT 模式。这两个模式在课程开始时就讲过了(“Linux 网络连接的三种方式”)
        VMnet1(Host-Only 模式):
        • 网络类型仅主机模式(Host-Only Networking)。
        • 核心功能
          • 虚拟机与宿主机(Host)之间可以通信。
          • 虚拟机之间可以互相通信。
          • 虚拟机无法访问外部网络(如互联网),外部设备也无法访问虚拟机。
        • IP 地址分配
          • 默认由 VMware 虚拟 DHCP 服务器分配(如 192.168.56.0/24 网段)。
          • 也可手动配置静态 IP,需与宿主机虚拟适配器在同一子网。

        VMnet8(NAT 模式)
        • 网络类型网络地址转换模式(NAT Networking)。
        • 核心功能
          • 虚拟机通过宿主机的 IP 地址访问外部网络(如互联网)。
          • 虚拟机之间可以互相通信。
          • 外部网络无法直接访问虚拟机(需手动配置端口转发)。
        • IP 地址分配
          • 默认由 VMware 虚拟 DHCP 服务器分配(如 192.168.152.0/24 网段)。
          • 虚拟机共享宿主机的 IP 地址,通过 NAT 协议转换通信。
        ipconfigifconfigping
        这三条指令在前面 “Linux 远程登陆” 部分其实也介绍过。
        ipconfig 用于在 Windows 终端中查询主机的 IP 地址;
        ifconfig 用于在 VMware 的 Linux 终端中查询虚拟机的 IP 地址;
        ping 在 Windows 终端和 Linux 终端中都可以使用,用于测试是否能够连接某个 IP 地址,如 ping 192.168.1.2ping 也可以用于测试是否能够连接上某个网址,比如 ping www.baidu.com
        测试连接(VMnet1 ↔ Linux;VMnet2 ↔ Linux)
        首先在 Windows 终端(Win+R 输入 cmd)中输入 ipconfig ,查询 Windows 主机目前可用的 IP 地址。
        在我的主机中查询的结果如下:
        notion image
        只有红框部分的三个适配器是具有 IP 地址的,无线局域网适配器就是 Wifi 的局域网 IP

        由于 VMnet1 是仅主机模式,也就是说,通过 VMnet1,Windows 主机与 Linux 是可以直接通信的。在您自己的设备上查询到 VMnet1 的 IP 地址(即 IPv4 地址)后,回到 Linux 终端,在终端中输入 ping [IP] ,即可看到 Linux 系统与主机之间的通信,下图是在 Xshell 中测试的结果。(在 VMnet1 的模式下,无需取消 Windows 的防火墙,因为 Linux 没有与外界通信
        notion image

        如果使用 VMnet8 的 IP 地址,表示 Linux 系统使用 NAT连接 模式与主机通讯,并通过主机访问互联网。
        首先在终端中输入 ping [IP] ,可以看到 Linux 终端会一直卡在第一条发送命令上,不会像前面 VMnet1 模式一样每隔一段时间接收一段数据,也就是说没有成功发生通信,这是因为 Windows 默认开启了防火墙。
        notion image
        因此,接下来我们要做的就是暂时关闭防火墙,首先打开“设置”,然后按照如下步骤操作:
        notion image
        最后要记得点击页面右下角的确认键。在点击确认的一瞬间,先前 Linux 终端中停滞的通信就开始了,每隔一段时间会有数据发送过来。
        notion image

        Linux 通过无线局域网访问外部网络
        Linux 终端使用无线局域网的 IP 地址即便没有关闭防火墙也是可以连通的。
        首先,我们将防火墙重新打开,在 Linux 终端中输入 ping [IP] ,此时的 IP 地址采用无线局域网的。
        notion image
        可以发现,即遍打开了防火墙,Linux 也能够对外部网络进行访问。通过无线局域网访问外部网络的流程如下图所示:
        借用韩老师的流程图。
        借用韩老师的流程图。
        【root 权限】更改 Linux 的 IP 地址(设置固定的 IP 地址)
        Linux 系统的 IP 地址有两种方式可以设定——自动设定,手动指定。
        自动设定
        登陆后, 通过界面的来设置自动获取 ip。
        特点:Linux 启动后会自动获取 IP,缺点是每次自动获取的 IP 地址可能不一样。
        手动指定(固定 IP)【程序员推荐】
        在进行下面的操作前,请先快照(或克隆)备份你的虚拟机。弹幕中好多人不知道哪步操作错了,很多都要重装系统。
        首先通过 Linux 终端打开指定配置文件,vi /etc/sysconfig/network-scripts/ifcfg-ens33
        打开配置文件后,需要进行更改的内容如下:
        我修改后的 vim 文件
        这个可能需要根据自己的虚拟机配置来,我使用的是老师的版本 CentOS7.6,大家可以比对以下除了修改部分以外的信息是否和这个一致,如果一致直接复制粘贴过去就行。
        将文件修改好以后,按照下图所示的操作修改 NAT 的子网 IPNAT 网关
        notion image
        确认信息和图中所示部分无误后,点击 “应用” 执行修改。最后再点击确定。
        然后右键 Vmware 桌面,打开终端,在终端中输入 reboot 重启虚拟机(或使用 service network restart),虚拟机开机后登录,再次打开终端,输入 ifconfig 查询当前虚拟机的 IP 地址,可以看到 IP 地址已经更改为了 192.168.200.130 ,修改成功😆。
        经测试,是可以正常上网的,大家如果按照上面的步骤来操作,应该不会出现问题。
        【root 权限】修改 Linux 主机名
        Linux 的主机名主要用于日志记录,脚本的自动化等,通过 hostname 命令即可查看当前虚拟机的主机名。
        如果我们想要自定义自己的主机名,需要到 /etc/hostname 中进行修改。首先使用 vim /etc/hostname 打开配置文件,配置文件中第一行显示的内容即为当前的主机名,将第一行内容修改为需要自定义的内容后保存退出即可完成修改。
        完成修改后,再次输入 hostname 命令会发现主机名仍然没有变更,这是因为我们主机名的修改是重启后才能生效的,因此还要输入 reboot 重启
        设置 host 映射
        这部分先介绍 Windows 下host 映射的修改,再介绍 Linux 系统下 host 映射的修改。
        IP 地址通常都是比较难记的,特别是在数量多的情况下,比起记忆 IP 地址,生动形象的名字显然更具有竞争力;
        如果我们希望通过自定义的名字来访问某个 IP 地址,可以在 Windows 的 host 文件夹中进行修改。
        打开文件资源管理器,按下键盘的快捷键 Alt+D 选中地址栏,在地址栏中输入 C:\Windows\System32\drivers\etc 进入 etc 文件夹,然后右键 hosts 文件,找到使用”记事本编辑“的选项并点击。
        hosts 文件的最后输入 192.168.200.130 linuxIP 地址具体以 Linux 终端中 ifconfig 命令下显示的为主),添加后按下 Ctrl+S 保存并关闭文件。
        按下 Win+R 输入 cmd 打开终端,在终端中输入 ping linux 即可访问到 linux 系统,如下图所示:
        notion image

        如果我们想要在 Linux 系统中修改 host 文件以方便我们在 Linux 系统中通过自定义名字访问 IP 地址,我们需要在 Linux 终端中输入 vim /etc/hosts 打开 Linux 的配置文件。
        在 Windows 终端中输入 ipconfig 查询我们想要自定义名字的 IP 地址,比如 192.168.200.1 ,然后返回 Linux 系统,在文件最后添加上 192.168.200.1 vmnet8
        然后保存并退出 vim 文件,在终端中输入 ping vmnet8 即可看到 vmnet8 可以正常的使用。
        notion image
        DNS 与 DNS 解析
        DNS 是 domain name system 的英文缩写,意思是“域名系统”。DNS 是互联网上域名和 IP 地址相互映射的一个分布式数据库。
        DNS 域名解析的过程如下(本地查询 → DNS 服务器查询 → 结果返回):
        1. 本地查询
          1. 浏览器先查自身缓存 → 无则查操作系统缓存 → 若仍无,检查 hosts 文件是否有手动配置的域名-IP 映射。
        1. DNS 服务器递归查询
          1. 若本地无结果,向 本地 DNS 服务器 发起请求,依次查询:
            • 根域名服务器 → 顶级域名服务器(如 .com)→ 权威域名服务器(如 baidu.com),最终获取目标 IP。
        1. 结果返回与缓存
          1. 解析成功后,IP 地址逐级返回并缓存到本地,后续请求直接使用缓存加速访问。
            若解析失败,则会出现域名不存在的提示。
        在 Windows 终端中,输入 ipconfig /displaydns 指令可以查询主机的域名解析记录,输入 ipconfig /flushdns 则可以清空所有的记录。

        通过上述的过程,不法分子可能会修改主机 hosts 文件的配置,在你输入正确的网址时访问到错误的网站(比如它的钓鱼网站),获取你的个人信息。
        📌
        由于我并非是科班出生的,也没有系统学习过计算机网络的相关知识,因此关于什么是子网掩码、什么是网关等知识这里就不做说明了,后面我如果有时间,且有精力学计算机网络,会将这部分知识进行补充。当然,如果有小伙伴愿意补充,非常欢迎!!
        进程与服务管理
        进程管理(ps
        什么是进程、前台、后台
        每个进程都是程序的一个运行实例,比如 微信聊天、浏览器上网、音乐播放,都是不同的进程在进行工作。而操作系统作为一个“总管”,会决定哪些进程先工作,哪些进程分配多少资源。
        进程通过“前台”和“后台”两种方式存在。前台与后台的概念可以类比于舞台剧中的演员与奏乐队,演员是在台前给观众们看的,而奏乐队是在后台配合演员的表演进行配乐的。
        前台的程序是直接与用户交互的,用户可以点击选项进行操作,而后台一般是用户不可见的,前台操作的具体实现可能由后台的服务器来完成。很多系统服务都是以后台的方式从系统开机开始一直运行到系统结束。
        无论是在 Windows 中还是在 Linux 中,每个进程都会被分配一个进程号,英文使用 pid 来表示,应该是 process identifier 的缩写。
        ps 指令(显示系统当前进程)
        ps 指令为 Process Status 的缩写,意思是进程状态。
        ps 指令可选参数介绍
        下面的可选参数并没有具体的英文单词与之对应,只是遵循传统的命名习惯。
        可选参数
        含义
        a
        显示所有与终端关联的进程​(包括其他用户)。
        u
        显示 ​详细资源占用​(CPU、内存等)。
        x
        显示 ​无控制终端的进程​(可以理解为后台进程,如后台服务)。
        -e
        显示所有进程(无论是否关联终端),ps -e 相当于 ps -ax
        -f
        显示完整格式信息,包括进程的 用户 UID、PID、PPID(父进程 ID)、启动时间、完整命令路径,但不会显示 CPU 占用资源。
        aux 三个参数常常一起搭配使用,侧重于查看进程的资源占用,使用时最好用 ps aux 指令, ps -aux 指令虽然也可以输出,但并不符合规范;
        -ef 两个参数常常一起搭配使用,侧重于查看子进程的父进程,使用方法为 ps -ef (短横线不能省略)。
        📌
        aux-ef 指令是两种不同的显示风格(前者为 UNIX,后者为 BSD ),不能混合起来使用。
        ps aux 指令输出的各列内容含义
        常用于查看精确的资源消耗。
         
        列名
        含义
        USER
        进程的 所有者(谁启动的进程)。
        PID
        进程的 唯一 ID(用于管理进程,如 kill PID)。
        %CPU
        进程 占用 CPU 的百分比(精确值)(多核下可能超过 100%)。
        %MEM
        进程 占用物理内存的百分比
        VSZ
        进程的 虚拟内存大小(单位 KB)。
        RSS
        进程 实际使用的物理内存(单位 KB)。
        TTY
        进程关联的 终端设备? 表示无终端,如后台服务)。
        STAT
        进程的 状态码(见下方状态码说明)。
        START
        进程的 启动时间或日期。具体的状态码见右侧的表格。
        TIME
        进程 累计使用的 CPU 时间(格式:分钟:秒)。
        COMMAND
        启动进程的 命令名称或路径-f 选项可显示完整命令)。
         
        其中 STAT 列各个字符的信息解读(通常由 状态码 或 状态码+附加属性字符 表示):
        状态码:
         
        代码
        类型
        说明
        R
        运行状态
        进程正在运行或可运行(在运行队列中等待 CPU)。
        S
        可中断休眠
        等待事件完成(如用户输入、网络响应)。
        D
        不可中断休眠
        进程正在等待 I/O 操作(如磁盘读写),无法被信号中断。
        Z
        僵死状态
        进程已终止,但父进程未回收其资源。
        T
        暂停状态
        进程被信号(如 SIGSTOP)暂停(可通过 fg/bg 恢复)。
        t
        跟踪暂停
        进程正在被调试器(如 gdb)跟踪。
        X
        死亡状态
        进程完全终止(仅在瞬时显示)。
         
        附加属性字符:
         
        符号
        含义
        <
        高优先级进程(nice 值负数)。
        N
        低优先级进程(nice 值正数)。
        s
        会话领导者(Session Leader)。
        l
        多线程进程(CLONE_THREAD 标志)。
        +
        位于前台进程组(如终端交互进程)。
        L
        内存页被锁定(常用于实时任务)。
        ps -ef 指令输出的各列内容含义
        常用于查看某个进程的父进程。
        列名
        含义
        UID
        进程所有者用户 ID
        PID
        进程 ID
        PPID
        父进程 ID(父进程的 PID),parent pid
        C
        CPU 占用率(粗略值)
        STIME
        进程启动时间
        TTY
        关联的终端设备
        TIME
        累计 CPU 占用时间
        CMD
        启动进程的完整命令(含参数)
        父进程的解读:
        notion image
        PPID = 0 时,表示该进程为系统启动时执行的第一条进程;当 PPID = 2 时,表示该进程的父进程为 PID = 2 的进程,即图中第二条进程,其他的也是如此解读。
        ps -efps aux 指令的对比
        对比项
        ps -ef(Unix 风格)
        ps aux(BSD 风格)
        选项风格
        带短横线(-e-f
        无短横线(aux
        设计来源
        遵循 UNIX System V 规范
        源自 BSD 系统
        主要用途
        显示进程层级关系和完整命令路径
        查看进程的资源占用(CPU、内存等)
        输出信息
        更侧重进程的父进程和启动信息
        侧重进程的资源消耗详情
        可以根据输出来选择具体的应用场景。
        如何查看某个具体用户的进程
        使用方法为 ps -ef | grep xxx ,比如 ps -ef | grep rootps aux | grep jack
        sshsshdbash
        1. SSH(Secure Shell)
          1. SSH 是一种加密的网络协议,我们可以通过 SSH 协议来实现安全地远程登录,传输文件或执行命令,防止黑客窃听。
            比如我们使用 Xshell 来登录 Linux 系统,虽然现在是在同一台电脑上操作的,但它们之间也是通过 SSH 协议来对话的。
        1. SSHD(SSH Daemon)
          1. daemon 的意思是“守护进程”(守护进程在“服务管理”部分会具体介绍),SSHD 即 SSH 的守护进程。守护进程一般都是运行在后台的。
            SSHD 的作用是 24 小时监听来自客户端的 SSH 连接请求,在验证了客户端的身份后允许其登录。
            比如我们在 Xshell 中通过 IP 地址建立和 Linux 系统之间的联系,必须要输入正确的用户名和密码才能够登录,进而实现文件的传输或命令的执行。
        1. Bash(Bourne-Again Shell)
          1. Bash 是命令行翻译工具,用于将用户输入到终端的指令翻译成系统能够理解的语言。
        ps aux | grep sshdps aux | grep bash
        ps aux | grep sshd 这条指令用于查看所有与远程登录相关的进程,查看有哪些用户远程登录到了服务器中,可以方便后续对进程进行终止;
        ps aux | grep bash 这条指令用于查看所有和 命令行界面(Bash) 相关的进程,查询有多少个终端窗口或脚本在运行,方便后续对这些进程进行终止。
        【root 权限】终止进程(killkillall
        终止自己的进程时可以不用 root 权限,但是终止其他用户的进程或是系统进程,需要 root 权限
        终止进程可以通过 kill 指令和 killall 指令来完成,当某个进程执行一半需要停止或是已经消耗了很大的系统资源时, 可以考虑这两条指令。
        两条指令的使用方法都是 kill 进程号(pid) ,只不过 kill 只会停止某个进程,而 killall 会停止某个进程包括其所有的子进程。
        kill -9 pid 用于强制停止某个进程(有时候使用 kill pid 停止某些特殊进程时,系统会认为我们误触,需要使用此指令强制停止)。比如我们通过 ps aux | grep bash 指令观察到当前有两个终端同时打开,复制我们需要关闭的终端的 pid,可以使用 kill -9 pid 来将其关闭。

        案例说明:
        1. 终止远程登录服务 sshd,在适当时候再次重启 sshd 服务
          1. 首先通过 ps aux | grep sshd 查看当前的远程登录设备,将最后末尾为 /usr/bin/sshd -D 的进程号 1224 (根据您查询的结果而定)记录下来,然后 Kill 1224 ,所有的远程登录设备就都会被切断,因为 SSHD 服务已经终止了。
            notion image
            如果想要恢复 SSHD 服务,可以通过 bin/systemctl start sshd.service 来重新启动服务。
            📌
            虽然并不清楚很多输出内容的具体含义,但韩老师开课时曾经说过,Linux 学习要学会适当地囫囵吞枣,很多现在不懂的知识需要结合后面的知识才能理解,因此细节方面未来再抠。
        1. 强制终止某个终端。
          1. 首先在打开一个终端的基础上,再右键桌面打开另一个终端,通过 ps aux | grep bash 指令查看刚刚打开的终端(查看现在的时间和哪一个最接近,且结尾是 bash),找到后 kill -9 2867 即可(下图为我的操作):
            notion image
        显示进程树(pstree
        直接使用 pstree 即可在终端中输出当前的进程树,如下图所示:
        notion image
        图中使用方框框住了部分内容,红框部分表示的就是父进程,父进程右侧使用绿框框住的部分就是其子进程。

        两个常用的可选参数: -u-p
        pstree -u 可以显示每个进程是由哪个用户执行的(帮助文档中关于 -u 指令的描述:显示 uid 过渡。只要进程的 uid 与其父进程的 uid 不同,新的 uid 就会显示在进程名称后面的括号中。);
        pstree -p 可以显示每个进程的 pid
        【root 权限】服务管理
        什么是服务
        服务(Service)本质上也是一个进程,通常是在后台运行的,通常是监听某个端口,等待端口发送过来的请求,因此又称为是守护进程。比如 SSHD 就是响应远程登陆设备的端口请求。
        事实上,服务与后台程序、守护进程这三个都描述的是同一个东西,三者是等价的。
        service 管理指令(旧系统指令)
        该指令是旧的 CentOS 系统(CentOS 7 之前)使用的指令,目前很多服务都已经不再使用 service 指令来执行了,而是通过 systemctl 指令(前面“运行级别”部分介绍过)来执行。
        service 指令主要存放在 /etc/init.d 目录下,可以通过 ls -l /etc/init.d 来查看,不过我在 Xshell 中操作时,需要先 cd /etc/init.d,然后再 ll 才可以显示全部的指令,否则只会显示一个软链接(具体如下图所示)。
        notion image

        service 指令的使用方法: service 服务名 [start | stop | restart | reload | status]
        setup 指令
        在终端中输入 setup 指令并回车,会弹出一个蓝色窗口,在窗口中可以设置开机自启动的服务。
        蓝色窗口中通过上下左右键移动,按下回车表示选择选项,比如选择“系统服务”选项。进入“系统服务”选项中,可以看到有很多的服务,通过上下键移动到我们所需的服务选项后,按下“空格”表示选择或取消选择(此处按“回车”没用)。选择完成后按下“Tab”键将光标移动到“确认”处,回车即可进行确认。
        notion image
        系统开机流程
        notion image
        其中 BIOS(全称:Basic Input/Output System,基本输入输出系统)执行硬件自检(POST, Power-On Self-Test),初始化硬件设备。
        【回忆】运行级别(target
        传统的运行级别(RunLevel)
        运行级别
        名称
        终端指令
        用途
        0
        Halt(停机)
        init 0
        关闭系统。与 shutdown -h nowhalt 指令效果相同。
        1
        Single-User
        init 1
        单用户模式(仅 root 权限,无网络,用于系统维护或找回丢失密码等情形)。
        2
        Multi-User
        init 2
        多用户模式(无图形界面和网络,部分服务不启动,一般不使用)。
        3
        Multi-User + Network
        init 3
        多用户模式(带网络服务,命令行界面,服务器常用)。
        4
        保留
        init 4
        未定义,用户可自定义。
        5
        Graphical
        init 5
        多用户模式 + 图形界面(如 GNOME、KDE,桌面版默认)。
        6
        Reboot(重启)
        init 6
        重启系统。与 shutdow -r nowreboot 指令效果相同。
        传统的运行级别 0~6 是 SysVinit 的概念,只能死板的执行上面的这些指令,不能自定义组合功能,切换模式时要按顺序一个个启动服务,速度较慢。
        传统的运行级别通过 init n 指令执行(视频中老师介绍的方式),如果我们想要切换到运行级别 3,可以在终端中输入 init 3.
        现代的 target 指令
         target 是 systemd(现代 Linux 的系统管理工具)对传统运行级别(Runlevel)的升级和扩展。
        target 指令不仅兼容了传统的运行级别,并且更加灵活,可以创建自己的 target,按需组合服务;同时,可以实现多个服务并行启动,加快系统初始化速度。
        如何使用 target 实现传统的运行级别 0~6?
        传统运行级别
        systemd target
        终端指令
        说明
        0(关机)
        poweroff.target
        systemctl poweroffsystemctl poweroff.target
        关闭系统。
        1(单用户)
        rescue.target
        systemctl rescuesystemctl isolate rescue.target
        仅 root 权限,用于系统维护。
        3(多用户命令行)
        multi-user.target
        systemctl isolate multi-user.target
        带网络服务的命令行模式。
        5(图形界面)
        graphical.target
        systemctl isolate graphical.target
        图形界面模式(如 GNOME、KDE)。
        6(重启)
        reboot.target
        systemctl rebootsystemctl isolate reboot.target
        重启系统。
        当然,在现代的 Linux 终端中,仍然可以使用 init n 命令,但系统内部仍会转换为上述终端指令执行。
        常用的 target 指令介绍:
        【无需 root 权限】systemctl get-default
        查看当前的目标(target),即当前的运行级别。
        systemctl set-default 名称.target
        设置默认启动目标,即设置默认的运行级别。
        systemctl set-default graphical.target 就会将运行环境默认设置为 图形界面。
        ‼️
        注意,千万不要运行 systemctl set-default poweroff.targetsystemctl set-default reboot.target将运行环境设置为关机或重启状态,否则会陷入关机重启死循环中。
        chkconfig 指令(设置不同运行级别下自启动的服务)(旧系统指令)
        该指令与 service 一样,都是旧的 CentOS 系统(CentOS 7 之前)使用的指令,目前很多指令已经被 systemctl 替代。
        该指令用于给服务的各个运行级别 设置自启动 或是 关闭自启动。chkconfig 指令能够操作的服务也位于 /etc/init.d 目录中。
        可以通过 chkconfig --list 指令查看可以进行操作的服务;
        可以通过 chkconfig 服务名 --level n on/off 指令设置运行级别 n 下“服务名”的自启动或关闭,如 chkconfig network --level 2 off
        systemctl 指令(新系统服务管理指令)
        systemctl 指令主要存放在 /usr/lib/systemd/system/ 目录下,可以通过 ll /usr/lib/systemd/system/ 来查看。
        systemctl 指令的使用方法:
        • root 权限systemctl [start | stop | restart | status] 服务名
          • 短暂启用或关闭某个服务,系统重启后恢复原状态systemctl status 服务名 可以查询当前的服务是否处于启用状态。
             
        • root 权限systemctl enable 服务名 【启用】 或 systemctl disable 服务名 【关闭】;
          • 设置服务开机自启动或永久关闭)指令执行后需要重启才生效。
             
        • 【无需 root 权限】systemctl list-unit-files [| grep 服务名]
          • 查询所有服务的自启动状态)方括号表示可选,直接使用 systemctl list-unit-files 会列出所有服务的自启动状态;可以通过 grep 指令筛选出我们想要查询的服务。
            比如 systemctl list-unit-files | grep firewalld 可以查询防火墙相关的服务(也可以使用 systemctl list-unit-files | grep firewalld.service
             
        • 【无需 root 权限】systemctl is-enabled 服务名
          • 查询某个服务是否是自启动的)比如 systemctl is-enabled firewalld (或 systemctl is-enabled firewalld.service)可以查询防火墙服务的开启状态,若开启则返回 enabled ,反之为 disabled

        防火墙服务测试案例:
        1. 首先,需要打开 Windows 的 telnet 服务。
          1. 依次点击“开始”→“控制面板”→“程序”,在“程序和功能”中找到并点击“打开或关闭Windows功能”进入Windows系统功能设置对话框;找到并勾选“Telnet客户端”和“Telnet服务器”(如果有)。
        1. 其次,打开 Linux 防火墙,systemctl start firewalld
        1. 在 Windows 中打开 cmd 窗口(Win+R 输入 cmd),输入 telnet 192.168.200.130 111(根据自己的 IP 地址而定,暂时不用知道为什么是 111 端口),可以发现 Windows 是无法访问到 Linux 系统的;
        1. 接着,关闭 Linux 防火墙,systemctl stop firewalld
        1. 在 Windows 中打开 cmd 窗口再次输入 telnet 192.168.200.130 111 ,可以发现成功连接。
        【root 权限】Linux 防火墙
        防火墙可以理解为是 Linux 系统的大门(类比小区大门),而 Linux 系统中的各个端口就是就是 Linux 的小门(类比小区中自己的家门)。
        当防火墙启用时(小区大门紧闭),只有被允许的外来服务能够访问端口(只有得到小区户主的允许,亲戚朋友才能够进入小区),但外来服务无法访问不被允许的端口(亲戚朋友进入小区后无法进入到其他人的家里,只能到户主家里);
        当防火墙关闭时,所有的外来服务都能够访问端口,这种状态显然是十分危险的。

        下面来介绍防火墙端口配置的常用指令,用于查询、添加或移除防火墙中的某个端口:
        下面的指令中要特别注意哪些地方有空格,不要随意加入空格,尤其是等号的两侧不要加上空格
        1. firewall-cmd --permanent --add-port=端口号/协议
          1. 该指令能够将 Linux 的某个端口永久添加到防火墙的可访问名单中,相当于户主永久允许外来人员访问自己的家;
            其中的端口号就是我们要加入可访问名单的端口,协议可以通过 netstat -anp | more 指令(后面会介绍该指令)来查看(下图中绿框部分)。
            notion image
            我们需要先在红框部分找到需要设置的端口号,然后再找到绿框部分对应的协议。比如我们选择 111 端口,那么其协议为 tcp 协议。
            firewall-cmd --permanent --add-port=111/tcp
        1. firewall-cmd --permanent --remove-port=端口/协议
          1. 该指令能够将某个端口永久从外部可访问名单中移除,相当于户主不允许外来人员访问自己的家。
        1. firewall-cmd --reload
          1. 该指令用于加载防火墙的相关设置,在前面两条指令中的任一条执行后,都必须执行该指令,这样设置才能生效。
        1. 【无需 root 权限】firewall-cmd --query-port=端口/协议
          1. 可以查询某个端口是否处于外部可访问的名单中,如果在,则返回 yes ,反之,则返回 no

        使用案例:
        1. firewall-cmd --permanent --add-port=111/tcp
          1. 将 111 加入防火墙可访问名单。
        1. firewall-cmd --reload
          1. 重新加载防火墙相关设置。
        1. firewall-cmd --query-port=111/tcp ;→ yes
          1. 查询 111 端口是否处于可访问名单中。
        1. (Windows cmd)telnet 192.168.200.130 111
          1. 在 Windows cmd 测试是否能够成功访问 111 端口
        1. firewall-cmd --permenant --remove-port=111/tcp
          1. 将 111 端口从防火墙可访问名单中移除。
        1. firewall-cmd --reload ;(关闭的时候容易忘记这一步)
          1. 重新加载防火墙相关设置。
        1. firewall-cmd --query-port=111/tcp ;→ no
          1. 查询 111 端口是否成功从可访问名单中移除。
        动态监控网络
        top 指令介绍
        如果需要动态显示 Linux 系统的进程状态,可以使用 top 指令,与 ps 指令类似,也可以用于查看系统的 pidcpu 占用情况。
        top 指令比起 ps 指令,优点在于可以动态更新当前进程情况。
        top 指令可以直接在终端中输入使用,默认是每隔 3 秒钟更新一次。如果希望 top 指令按照自定义的时间进行更新,可以使用 top -d n 指令,表示每隔 n 秒动态更新一次。输入 top 指令进入动态监控窗口后,可以按下键盘上的 q 键退出窗口。
        使用 top 指令后系统输出如下图所示:
        notion image
        上图信息的解释:
        • 绿框部分表示的是当前时间为 08:44:10 ,系统已经运行了 1 min,目前只有 1 个用户;
        • 红框部分表示当前系统的负载均衡,如果三个值的平均值大于 0.7,说明当前系统的负载均衡超过了 70 %,系统过载;
        • 蓝框部分表示的是当前系统的任务(进程)数量,总数为 292 ,正在运行的进程有 1 个,有 291 个进程处于休眠状态,0 个停止进程, 0 个僵死进程。
          • 关于僵死进程,表示的是已经不再执行但仍然占用系统内存空间的进程,这类进程如果过多,会拖累整个系统,因此要及时清理。
        • 黄框部分表示当前的 CPU 占用情况,us 表示的是用户占有的 CPU,sy 表示的是系统占用的 CPU,id 表示当前系统空闲的 CPU 情况;
        • KiB Mem 表示的是内存占用情况,数字表示的是字节数,2027856 以三个数字为一组划分 2,027,856 ,容易看出总的内存为 2G 左右,当前空闲的内存为 1,149,688 字节,即 1.1G 左右;目前使用了 499,228 也就是 500MB 左右,缓冲区为 378,940 也就是 300 MB 左右。
        • KiB Swap 表示的是交换内存占用情况,读取方法与 KiB Mem 相同。
        💡
        重点关注的是 CPU 占用情况和内存占用情况,如果空闲的内存少于系统的 30%,说明内存不足了,需要向上面反映。
        top 指令的可选参数
        可选参数
        含义
        -d n
        用于指定 top 输出的进程更新频率,每隔 n 秒更新一次
        -i
        top 不显示任何闲置或僵死进程
        -p pid
        用于让 top 动态监控某个进程的状态
        top 指令输出进程的更多操作
        notion image
        对进程进行排序:
        • 在动态监控窗口中,按下键盘上的大写键,再按下 P 表示按 CPU 使用率进行降序排序;
        • 按下键盘上的 M 表示按内存的使用率进行降序排序;
        • 按下键盘上的 N 表示以 PID 进行降序排序。
        查看特定用户的进程状态:
        • 按下键盘上的 u ,输入用户名称即可监控有关某个用户的进程;
          • 如果内容输出错误,可以按下 Ctrl+删除键 进行删除。
        kill 某个进程:
        • 按下键盘上的 k ,输入要结束的进程的 pid 即可。
        退出动态监控窗口:
        • 按下小写的 q 退出动态监控窗口。
        查看系统网络情况
        netstat 使用方法
        netstat(Network Statistics)是一个功能强大的网络工具,用于显示 网络连接、路由表、接口统计 等信息。
        netstat 的常用可选参数如下表所示:
        可选参数
        含义
        -a / --all
        显示 所有活动连接监听端口(包括监听和已建立的)。
        -t / --tcp
        仅显示 TCP 协议 相关连接。
        -u / --udp
        仅显示 UDP 协议 相关连接。
        -l / --listening
        仅显示 处于监听状态 的端口(服务)。
        -n / --numeric
        直接显示 IP 地址和端口号(不解析为域名或服务名)。
        -p / --program
        显示 关联的进程名和 PID(需 root 权限查看其他用户的进程)。
        -r / --route
        显示 系统路由表(类似 route -n)。
        -s / --statistics
        显示 网络统计信息(如丢包、错误包数量)。
        -c / --continuous
        持续输出信息(按秒刷新)。
        -n 参数的效果
        notion image
        如图所示,在 -n 参数作用下,可以显示出 Local AddressForeign Address 的具体 IP 地址。
        📌
        注意,在使用上面的指令时,不要将 -a 参数与 -l 参数一起使用,-l 参数的作用会被 -a 参数掩盖。
        📌
        netstat 指令常与 grep 指令搭配使用,比如 netstat -anp | grep sshdnetstat -anp | grep listen
        什么是 IP 地址和端口
        首先,需要先明白端口和 IP 地址具体是什么。对于 Windows 和 Linux 系统,在工作时都会有一个 IP 地址,将 Windows 类比于我们的家,Linux 类比于我们的公司,那么 IP 地址相当于是家和公司的地址。
        在家中有很多的家庭成员,每个家庭成员都有一个自己的电话,而在公司中,每个部门也有部门的座机电话,家的电话相当于是家里的不同端口,而公司部门的电话相当于是部门的端口。
        一般来说,家和公司的地址是固定的,也就是 IP 地址是固定的;不同的端口对应的服务是固定的,也就是家庭成员和公司部门的座机电话是固定的;一个 IP 地址可以对应多个不同的端口,因为每个家庭成员和公司部门都有一个独属于自己的电话。当某个家庭成员想要与公司部门通信时,可以从 Windows 的特定端口访问 Linux 的特定端口;当公司部门想要联系家庭中的某个成员时,也可以通过 Linux 的特定端口访问 Windows 的特定端口。
        可以通过韩老师下面这张图来辅助理解:
        notion image
        netstat 输出各列的含义
        以下内容针对 netstat -anp | more 指令执行后输出的各列内容。
        notion image
        列名
        含义
        示例
        Proto
        协议类型(TCP/UDP)
        tcpudptcp6(IPv6)
        Recv-Q
        接收队列中暂存的数据量(字节),通常为 0 表示无堆积。
        0
        Send-Q
        发送队列中暂存的数据量(字节),通常为 0 表示无堆积。
        0
        Local Address
        本地 IP 地址和端口:  0.0.0.0:22:IPv4 所有地址的 22 端口;  :::22:IPv6 的 22 端口。
        192.168.1.5:22
        Foreign Address
        远程 IP 地址和端口0.0.0.0:*:表示无远程连接(监听状态);  192.168.1.10:5432:已建立的远程连接。
        0.0.0.0:*
        State
        连接状态(仅 TCP 协议显示): LISTEN:端口正在监听; ESTABLISHED:已建立连接; TIME_WAIT:等待关闭,该状态是为了确保某个连接的断开不是因为网络的临时波动引起的。比如当我们另外打开一个窗口登录 tom 用户时,netstat 会更新一个连接端口的状态;当我们此时将 tom 用户登出 logout 时,原先连接的端口会有一个超时等待,达到一定时间后才会恢复 LISTEN 状态。
        ESTABLISHED
        PID/Program name
        进程 ID 和程序名称(需 root 权限查看所有进程)。1234/nginx:进程 ID 1234 的 Nginx
        5678/ssh
        包的安装和卸载
        查询包的相关操作(只读)无需 root 权限,安装、更新、卸载等操作需要 root 权限。
        rpm 包介绍
        RPM是 RedHat Package Manager(RedHat 软件包管理工具) 的缩写, 类似 windows 的 setup.exe 。虽然 RPM 打上了 RedHat 的标签,但并不是红帽专用的,该理念是行业内公认的标准。
        rpm 包相关指令
        在使用 rpm 指令安装包时,不会自动解决依赖关系,常常会使用 yum 指令。
        查询 rpm 包
        1. q (query)
          1. 查询软件包信息,常用组合:
            -qa:a 表示 all。列出所有已安装的包(rpm -qa | grep firefox
            -qi:i 表示 info。显示包的详细信息(版本、描述等)
            -ql:l 表示 list。列出包内的所有文件路径
            -qf:f 表示 file。查询某个文件所属的包(如rpm -qf /usr/bin/vim
            -qR:R 表示 requires。显示包的依赖关系
        1. p (package)
          1. 针对未安装的.rpm文件进行查询,例如:
        安装 rpm 包的相关指令:
        rpm -i 包名称(install):
        安装指定RPM包,需配合文件路径使用,例如:
        • v:v 表示 verbose。显示安装详细信息(Verbose)
        • h:h 表示 hash。表示以进度条(#,哈希符号)显示安装进度
        • -test:仅测试安装过程,不实际执行(用于检查依赖冲突)
        • -nodeps: nodeps 表示 no dependencies。忽略依赖关系强制安装(可能导致软件无法运行)
        • -force:覆盖冲突文件或已安装的包
        • -prefix:指定自定义安装路径(如-prefix /opt
        卸载 rpm 包的相关指令:
        rpm -e 包名称 (erase):
        当 rpm 包不与其他包有依赖关系的时候,即该包存在与否并不影响其他包的运行时,可以直接卸载某个包,如 rpm -e firefox
        当 rpm 包与其他包有依赖关系时,如 rpm -e foo ,会提示报错:removing these packages would break dependencies:foo is needed by bar-1.0-1。此时系统会阻止我们卸载这个包,如果想要强制卸载,需要加上 --nodeps 参数,比如 rpm -e --nodeps foo
        rpm 包名的解读
        当我们使用 rpm -q firefox 指令时,会显示详细的 rpm 包名称,比如 firefox-91.11.0-2.el7.centos.x86_64
        其中,firefox 就表示包的简称,91.11.0 表示包的版本号,el7.centos.x86_64 表示包适用的操作系统,一般 _64 结尾的都是适用于 64 位操作系统的。
        如果出现了 i686i386 等一般表示 32 位系统, noarch 表示 32 位和 64 位通用。
        yum 相关指令
        yum 指令相比于 rpm 可以实现自动管理依赖关系。
        1. 查询系统已安装包、可安装包、未安装包;
          1. 安装相关包 ;
            1. 在查询到未安装包的包名后,可以使用 yum install 包名 来进行安装,比如 yum install firefox
              可选参数 -y 可以在安装时自动确认,如 yum install firefox -y
          1. 更新相关包;
            1. 卸载相关包;
              1. remove 参数表示卸载操作,比如 yum remove firefox ;同时,使用 -y 参数可以实现卸载过程的自动确认,如 yum remove firefox -y
            1. 清理缓存;
              1. 可以使用 clean 参数来清理缓存,使用方法为 yum clean all
            内核升级
            内核升级这部分内容韩老师安排在比较后面,不过我觉得它放在这里更合适。
            当有新的内核版本出现时,我们可以对内核进行升级。
            uname -a
            用于查看当前 Linux 系统的内核;
            yum info kernel -q
            检测当前系统的内核版本,显示可以用于升级的内核,该指令可以显示内核的详细信息(并不是版本越新越好,需要考虑系统兼容性的问题);
            yum list kernel -q
            查看系统已安装和可安装的内核版本,内核信息比较精简;
            yum update kernel
            升级内核;
            Linux 系统的备份与恢复
            这部分内容也是在比较后面学的,但这部分内容的学习其实并不依赖后面的知识,因此放在这里更为合适。
            由于 Linux 实体机无法做快照, 如果系统出现异常或者数据损坏, 那么后果将很严重,如果重装系统固然能够解决问题, 但会造成数据丢失。 因此我们要学习 Linux 备份和恢复技术。
            指令的安装
            备份和恢复采用的指令为 dumprestore
            首先,我们需要确认 Linux 系统中是否有这两个指令,验证的方法很简单,打开终端并分别输入 dumprestore 两条指令,如果输出“未找到命令”,那么就需要安装指令。
            notion image
            安装指令的方法为, yum install dump ,在安装了 dump 后也会同步安装 restore ,因此只需要运行一次指令即可。
            【root 权限】dump 备份
            dump 进行分区备份时,需要使用 root 权限。
            dump 是 Linux/Unix 系统中用于 文件系统级备份 的经典工具,专为 ext2/ext3/ext4 文件系统设计,用于应对服务器全盘崩溃的问题。
            dump 支持分卷和增量备份(所谓增量备份是指备份上次备份后修改/增加过的文件,也称差异备份)。但需要注意的是,dump 的增量备份只能针对分区进行,对于文件和目录,只能够进行完整备份。
            如何区别目录和分区?
            通过前面学过的 lsblk 指令即可进行区分。在终端中输入 lsblk ,观察 MOUNTPOINT 列,处于这一列中的文件路径为分区(下图的红框部分),其他的都为目录。
            notion image

            那么,具体该如何使用 dmup 指令进行备份呢?
            指令:dump [可选参数] 文件目录
            dump 的可选参数如下表所示:
            参数
            说明
            -0 ~ -9
            指定备份级别(0 为完全备份,1-9 为增量备份)。
            -f <file>
            指定备份文件路径(支持本地文件、磁带设备或远程路径)。
            -u
            更新备份记录文件 /etc/dumpdates,记录备份时间与级别。
            -j
            启用压缩,将备份后的文件压缩为 .bz2 格式,文件更小。
            -T 日期
            制定开始备份的时间日期
            -W
            显示已配置备份计划 —— 最后一次备份的层级,时间,日期(读取 /etc/fstab 和 /etc/dumpdates)。
            -w
            用于告知是否需要备份的检查选项,仅显示需要备份的文件。(这个指令等一下会详细介绍)
            -E <exclude>
            排除指定文件或目录(支持通配符)。
            📌
            关于参数 -0 ~ -9 ,使用的方法为:
            第一次备份时选择 -0 参数采用完全备份,在第二次到第九次备份时选择 -1 ~ -9 参数采用增量备份;
            当文件执行了 -9 的增量备份后,需要重新选择 -0 参数进行一次完全备份,也就是说,每进行 10 次备份为一轮。
            由于每次执行指令时的备份参数不一样,因此可以通过 shell 脚本(后面会介绍 shell 编程)来实现循环。
            示例:
            dump -0uj -f /opt/boot.bak0.bz2 /boot
            表示将 /boot 分区备份到 /opt/ 目录下,备份的文件名为 boot.bak0.bz2 。备份采用的方式为完全备份,同时会更新备份记录文件 /etc/dumpdates 并启用压缩。
            备份完成后,可以通过 dump -W 指令显示备份的层级、时间和日期。
            如何理解 dump -W 的输出信息
            notion image
            其中,第一列 /dev/... 表示的是已备份与未备份的分区,第二列括号表示的是分区对应的挂载点,第三列 Last dump 表示的是上一次的备份时间,never 表示从未进行过备份,Level 0, ... 表示的是上次备份的层级为 0,时间为 周六, 4 月 19 日, 09:01:20 2025年
            由于 /boot 分区已经备份,因此再次运行 dump -w 不会显示 sda1
            cat /etc/dumpdates
            查看备份的时间文件。

            如何理解指令 dump -w
            在前面的指令介绍中,dump -w 仅显示需要备份的文件,但这样的描述难免让人不太理解。其实 dump -w 的作用就是检查系统里哪些文件系统还没有被备份,或者需要新的备份。常用于写脚本时提前进行检查。
            在之前,我对 /boot 分区进行了备份,为了验证 dump -w 的作用,我修改了 /boot 分区中某个文件的名字,执行 restore -C -f /opt/boot.bak0.bz2 (这个指令在后面会学,这里知道是用于比较备份的文件和当前的文件是否一致即可)指令后,显示备份的文件与当前文件是不一致的。可是执行 dump -w 指令却只显示根分区需要备份:
            notion image
            后面通过查询资料发现,dump -w 指令是通过判断一个分区的“备份时间”是否“新鲜”来提示是否需要新的备份的。
            判断备份时间是否“新鲜”的方法为:
            • 查看 /etc/fstab 中第五列备份频率的值;
              • /etc/fstab 在前面介绍硬盘挂载的时候使用过,这里再进行回忆。
                【回忆】/etc/fstab 文件中各列的含义
                notion image
                列数
                字段
                含义
                示例解析
                第 1 列
                文件系统标识
                设备路径(如 /dev/sdb1)或分区的 UUID
                使用设备名 /dev/sdb1(建议改用 UUID,避免设备名变化导致挂载失败)。
                第 2 列
                挂载点
                文件系统挂载到的目录(必须是已存在的空目录)。
                挂载到 /newdisk 目录。
                第 3 列
                文件系统类型
                分区的文件系统类型(如 ext4xfsswap)。
                分区格式化为 ext4 文件系统。
                第 4 列
                挂载选项
                挂载时使用的选项(多个选项用逗号分隔)。
                defaults 表示默认选项:rw,suid,dev,exec,auto,nouser,async
                第 5 列
                dump 备份标志
                0 表示永远不纳入 dump -w/-W (后面备份部分会介绍)的检查。 >0(如 1、7、30):表示“当上次备份时间距今 ≥ 该值天数时,才算『备份过期』,需要补做一次备份”
                0 表示不备份此分区。 1 表示每天检查一次备份
                第 6 列
                fsck 检查顺序
                系统启动时检查文件系统的顺序(0 表示不检查,根分区通常设为 1)。
                0 表示不检查此分区(非系统关键数据盘可设为 0,根分区建议设为 1)。
            • 查看 /etc/dumpdates 中记录的上次备份日期。
            dump -w 指令是结合上面两个文件来判断是否要进行备份的。首先,dump -w 指令通过 /etc/fstab 文件来查看 /boot 分区的备份频率,我的是每天备份一次。
            notion image
            其次,通过 dump -w 指令会查看 /etc/dumpdates 中是否有关于 /boot 分区的备份时间,如果没有,那么会将 /boot 分区列入备份名单;如果有,那么会计算 /etc/dumpdates 中的上次备份时间距今是否超过了 /etc/fstab 中的备份频率,如果超过了也会将 /boot 分区列入备份名单。
            因此,之前我简单的修改文件名,无法让 dump -w 指令将 /boot 分区再次列入备份名单。明白了原理后,我通过 vim /etc/dumpdates/boot 分区的备份记录删除,再次运行 dump -w 指令,这一次成功将 /boot 分区列入了备份名单。
            notion image

            📌
            上述的示例中是将 /boot 分区备份到了 /opt 目录下,在实际的工作中,一般是将系统分区备份到其他服务器中,避免该服务器崩溃后,存放在该服务器里的备份也无法使用。
            dump 备份与 tar 压缩备份的区别:
            tar相比,dump能够更高效地处理块设备,并且支持增量备份,而tar更适合文件级别的备份。
            【root 权限】restore 恢复
            restore 命令用来恢复已备份的文件,可以从 dump 生成的备份文件中恢复原文件。
            使用语法为: restore [模式][选项]
            模式的选择有以下四种(四种不能混用,一次只能指定一种模式):
            1. -C 。对比模式,将备份的文件与当前文件进行对比。
            1. -i 。交互模式,进行还原时,restore 将依次询问用户。
            1. -r 。还原模式。
            1. -t 。查看模式,看看备份文件中有哪些文件。
            选项常用的参数为 -f 文件路径 ,比如 restore -t -f /opt/boot.bak0.bz2
            restore -C -f /opt/boot.bak0.bz2 对比模式中,如果备份的文件与当前文件不一致,会显示:
            notion image
            如图中红框部分所示,有一个比较错误(修改了一个文件的名字)。
            如果备份的文件与当前一致,会显示:
            notion image
            此时没有比较错误。

            restore -r -f /opt/boot.bak0.bz2 还原模式中,还原的位置取决于你当前所在的目录。
            如果创建了一个 /opt/boottmp 目录且当前位于 boottmp 目录下,那么就恢复到该目录中。但是用于恢复的目录必须是一个空目录
            现在假设我们将 /boot 分区进行了备份,那么如何将备份的数据恢复到原分区呢?
            当我们对分区进行备份时,如果进行了 增量备份,那么我们需要按顺序从 第 0 个备份到第 9 个备份(或目前最新备份)一次恢复。
            Linux 终端使用技巧
            清屏操作
            清屏操作在 Xshell 中与 Linux 终端中是通用的。
            当终端中进行了很多操作后,过去的操作内容会占满整个页面,因此可以通过清屏清除当前终端屏幕的可见内容,将光标移动到左上角。
            有三种方式可以清屏:
            1. clear
              1. 只清除屏幕可见内容,不重置终端状态。
            1. Ctrl+L:在终端处于活动状态时(就是点一下终端的界面),按下快捷键 Ctrl+L
              1. 与 clear 效果等同。
            1. Reset:在终端中输入 reset
              1. 不仅清空屏幕,还会完全重置终端的状态(如字符编码、光标行为、输入输出模式等)
            TAB 快捷键
            在终端中写指令时,按下键盘上的快捷键 TAB 可实现快速填充,比如要调用 apple.txt 文件,输入 ap 的时候按下 TAB 会将这个文件填充完整。
            键盘方向键
            按下键盘上的上下箭头可以调用本次使用终端时执行过的指令,如果关闭终端再打开,那么无法调用关闭前的指令,清屏操作不影响上下箭头的功能,只要不关闭终端就行。

            Shell 编程

            📝 Class Notes

            shell 编程的部分内容还需要有一些编程基础,个人觉得如果到了学习 Linux 的阶段,应该或多或少都会有 C 或 python 或 Java 等语言的基础,不然为什么要学习 Linux 呢。
            为什么要学习 Shell 编程?
            Shell 编程可以方便我们对服务器进行管理,通过编写脚本自动化地执行任务或管理系统。
            它的核心价值在于 简化重复操作、提升效率,尤其适合处理系统管理、文件操作、批量任务等场景。
            比如当我们需要定时执行备份或删除某个文件的任务时,我们就可以编写 shell 脚本来实现。
            什么是 Shell
            Shell 在之前我们也简单介绍过,相当于是我们与 Linux 系统之间的翻译官。
            我们使用 Shell 编写程序时,使用的是我们能够理解的编程语言,而要让 Linux 执行脚本中的内容,需要通过 Shell 来翻译成 Linux 能够理解的机器语言。
            Shell 脚本的创建和执行
            Shell 脚本一般是以 .sh 后缀来结尾的。在 Shell 脚本中,脚本需要以 #!/bin/bash 开头。
            简单程序示例(具体的代码含义在后面介绍):
            📌
            echo 语句相当于是 C++ 中的 cout ,python 中的 print()
            Shell 脚本的执行:
            脚本的执行有两种方式:
            ① 直接使用 sh 脚本名称 的方式来执行,比如 sh helloworld.sh
            ② 通过输入 shell 脚本的路径来执行脚本。
            这种方式需要先为 Shell 脚本添加执行权限,我们可以通过 ll 先查看 shell 脚本是否具有执行权限。如果没有相关权限,就使用 chmod u+x helloworld.sh
            然后通过 ./helloworld.sh (需要先 cd 进入脚本所在文件)或 /home/helloworld.sh (脚本的绝对路径)来执行脚本。
            📌
            如果脚本在当前目录下,不能通过 helloworld.sh 来调用,要使用路径的方式。
            Shell 变量
            使用变量来编写 Shell 脚本可以使代码更加灵活,当需要重复性的调用某个内容(比如一个路径)的时候,可以考虑将路径赋值给变量;同时,变量也可以用于接收用户输入的内容,增加了代码的灵活性。

            变量的命名:
            Shell 脚本中的变量一般使用大写的字母表示(一种规范,不强制),与其他语言一样,只能够使用数字、字母和下划线来表示变量,且变量不能使用数字开头。

            变量的赋值:
            变量的赋值可以通过 变量名=值 的方式进行,一定要注意等号两侧不能有空格。比如 A=100B=/home 等。

            变量的调用:
            使用变量时,需要在变量名前面加上 $ 符号,比如 A=$HOMEecho "A=$A"
            为了避免系统有时无法准确识别 $ 后面的变量名(产生报错),可以对变量名称的范围进行界定,即使用大括号将变量名包起来。括号用于显式告诉系统 括号中的整体内容为变量名称,可以进行调用。比如 ${VAR1} , ${BACKUP} ,其实现的效果与 $VAR1$BACKUP 是一样的。

            系统变量自定义变量:
            • 系统变量是系统预先定义好的变量,比如 HOME, PWD, SHELL, USER 等,通过 $HOME$PWD$SHELL 即可调用。
              • 在终端中输入 set 指令可以查看系统中已定义的全部变量。
            • 自定义变量是用户为了编写代码方便,自己定义的变量。

            变量定义的取消:
            在代码量比较大的时候,如果要取消变量过去定义的值,找到过去变量定义的位置可能并不容易,此时我们可以考虑使用 unset 指令。
            通过 unset 变量名 的方式可以帮助我们取消变量过去的赋值,相当于清空变量,但这并不会影响过去变量的作用,只会影响 unset 指令后面的代码。

            常量变量的定义:
            在 Shell 脚本中,可以使用 readonly 变量名 定义一个常量。比如 readonly A
            使用 readonly 定义的常量是只读变量,在定义后无法重新赋值,也无法通过 unset 指令撤销。
            通常是为了避免他人误修改代码中某个变量的值而使用的。由于使用该指令后变量的值无法更改,因此变量可以先提前进行赋值,再进行锁定。

            获取命令返回值($()`指令`
            在 shell 脚本中,可以使用终端中的一些指令,并将指令读取的结果赋值给变量,比如 date (输出当前的时间)。
            具体的方法为 $(指令名称) (推荐使用),也可以使用历史方法 `指令名称` (目前已不推荐)( `Esc 键下方)。
            添加环境变量(自定义系统变量)
            添加环境变量有以下几种方式:
            1. 直接修改/etc/profile 环境目录文件,配置全局环境变量;
              1. 具体步骤
                设置环境变量需要在 /etc/profile 文件中进行配置。主要步骤如下:
                1. cd /etc 进入 /etc 目录,通过 ll | grep profile 查看 /profile 文件是否存在(应该都是存在的);
                1. vim /etc/profile 进入 profile 文件,按下键盘上的大写 G 跳转到文件末尾,然后按下 i 打开编辑模式;
                1. 通过 export 变量名=变量值 的方式可以创建新的环境变量,在文件末尾输入 export MY_PATH=/home/zzdf (路径依据你自己的系统而定,确保路径要存在);
                1. 按下键盘 esc 键退出,按下大写的 Z Z 键退出;
                1. 重要)在新增环境变量后,需要进行刷新。输入source /etc/profile 即可对修改后的文件进行刷新,之后环境变量就可以正常使用了(可以通过 echo $MY_PATH 指令查看是否输出了之前定义的环境变量)。
                1. 环境变量定义完成,可以在 .sh 脚本中正常使用。
            1. 通过 export 命令将 shell 变量导出为环境变量;
              1. 使用方法:
                ① 查看所有的 shell 变量: exportexport | grep xxx
                ② 在当前的终端窗口中设置“永久”环境变量;
                第二种方法的具体实现
                • export <变量名称>=<值> ,如 export VAR=123
                • 先在终端中输入 <变量名称>=<值> ,然后再输入 export <变量名称> ,如先输入 MYVAR=234 ,再输入 export MYVAR
                • export <变量名称>=$PATH:<路径> (指定可执行文件的新搜索路径),比如 export PATH=$PATH:/opt/myapp/bin

                着重介绍一下第三种方式:
                其中,$PATH 为系统环境变量,表示可执行文件的搜索路径,: 表示两个路径之间的分隔符,上面指令的意思是将 : 后面的新路径添加到 $PATH 中,大家可以尝试使用 echo $PATH 将该环境变量的内容输出。
                路径顺序:
                添加到末尾$PATH:/new/path
                • 系统会先查找原有目录,最后查找新目录。
                • 适合添加工具目录(如自定义脚本),避免覆盖系统命令。
                添加到开头/new/path:$PATH
                • 系统会优先查找新目录
                • 适合覆盖系统命令(如使用自定义版本的 python)。
            1. 通过 env 命令设置环境变量;
              1. 使用方法:
                ① 查看所有的环境变量(包括 shell 变量):envenv | grep xxx
                ② 临时设置环境变量(只在 command 中有效):env <环境变量>=<xxx/xxx> command
                示例
                比如 env PATH=/home/ test.sh ,主要有以下三个步骤:
                1. 启动一个新进程,临时设置环境变量 PATH/home/
                1. 运行 test.sh 文件,在这个文件中,如果使用到了 PATH 变量,就表示 /home/ 这个路径;
                1. 脚本执行结束后,该环境变量失效。
            📌
            set 指令也能够列出环境变量,同时还会显示 shell 函数和普通的 shell 变量。
            多行注释
            可以通过下面的方式进行多行注释:
            📌
            注意,上面 :<<!! 指令都需要单独一行,注释的内容会呈现红色。
            位置参数
            位置参数其实类似于 C++ 中的 cin 和 python 中的 input() ,用于动态接收外部输入。
            比如我们希望 shell 脚本输出不同人的名字,如果在 shell 脚本内部写人名,那么要输出其他名字时就需要重新进入 shell 脚本中进行修改,不够灵活。而通过位置参数,脚本可以在调用时让用户手动输入姓名参数,根据用户输入的内容动态输出,这样就更灵活了。
            位置参数通过 $0$1$2...$N 这些符号来表示,具体如下:
            • $0:固定表示当前脚本名称。
            • $1~$9:调用脚本时,脚本名称后面的第 1 到第 9 个参数。
            • ${10}:脚本名称后面的第 10 个及以上的参数需要加上大括号。
            • $#:参数总个数。
            • $@:所有参数列表(每个参数独立)。
            • $*:所有参数合并为一个字符串。
            比如现在我们要实现前面动态输出人名的功能:
            预定义变量(用的不多)
            shell 脚本中使用。
            1. $$ (功能描述: 当前进程的进程号(PID) )
            1. $!(功能描述: 后台运行的最后一个进程的进程号(PID) )
            1. $? (功能描述: 最后一次执行的命令的返回状态。 如果这个变量的值为 0, 证明上一个命令正确执行; 如果这个变量的值为非 0(具体是哪个数, 由命令自己来决定) , 则证明上一个命令执行不正确了。 )
            执行运算的三种表达式
            常用于赋值运算,将表达式运算结果赋给一个变量。
            1. $((表达式)) 方式;
            1. $[表达式] 方式;
            1. expr `表达式` 方式(记住加空格);
              1. `esc 键下方,需要在英文状态下才能够输出,中文情况下输出是一个点 ·
            关于这三种表达式的特点,我咨询了一下 deepseek
            运算方式
            语法示例
            特点
            适用场景
            $(( ))
            echo $((5 + 3))
            1. Bash 内置运算符,效率高; 2. 支持复杂运算(如位运算、自增等); 3. 无需转义符号(如 * 可直接用)。
            现代脚本中的通用算术运算
            $[ ]
            echo $[5 + 3]
            1. 旧版 Bash 语法,功能与 $(( )) 类似; 2. 已逐渐被弃用,不推荐使用。
            旧脚本兼容(建议改用 $(( ))
            expr
            expr `5 + 3`
            1. 外部命令(非内置),性能较低; 2. 需严格空格分隔,且运算符需转义(如 * 要写成 \*); 3. 支持部分字符串操作(如长度计算)。
            兼容 POSIX 标准的简单运算或旧脚本
            📌
            因此,第一种方式应该是更为规范的方式。
            🌟🌟 $(()) 表达式中能够使用的运算符(deepseek)
            下面的运算符基本上和 C++ 中的是一样的,因此学过 C++ 的友友理解起来应该不难。没学过的建议多敲敲练一练。
            算术运算符:
            运算符
            描述
            示例
            结果
            +
            加法
            $((5 + 3))
            8
            -
            减法
            $((10 - 4))
            6
            *
            乘法
            $((2 * 6))
            12
            /
            除法
            $((15 / 4))
            3
            %
            取模
            $((10 % 3))
            1
            **
            幂运算
            $((2 ** 3))
            8
            比较运算符:
            运算符
            描述
            示例
            结果(1=真,0=假)
            ==
            等于
            $((5 == 5))
            1
            !=
            不等于
            $((5 != 3))
            1
            >
            大于
            $((10 > 5))
            1
            <
            小于
            $((3 < 5))
            1
            >=
            大于等于
            $((5 >= 5))
            1
            <=
            小于等于
            $((4 <= 5))
            1
            自增自减运算符:
            运算符
            描述
            示例
            结果(假设 a=5
            ++var
            先自增后取值
            $((++a))
            6a 变为 6
            var++
            先取值后自增
            $((a++))
            5a 变为 6
            --var
            先自减后取值
            $((--a))
            4a 变为 4
            var--
            先取值后自减
            $((a--))
            5a 变为 4
            自增自减运算符刚开始可能不太容易理解,这里提供代码示例供参考:
            大家可以到 Linux 中试试看下面两个代码,应该会有更深的理解
            逻辑比较运算符:
            运算符
            描述
            示例
            结果(1=真,0=假)
            ==
            等于
            $((5 == 5))
            1
            !=
            不等于
            $((5 != 3))
            1
            >
            大于
            $((10 > 5))
            1
            <
            小于
            $((3 < 5))
            1
            >=
            大于等于
            $((5 >= 5))
            1
            <=
            小于等于
            $((4 <= 5))
            1
            三元条件表达式:
            运算符
            描述
            示例
            结果
            条件 ? 值1 : 值2
            条件为真时返回值1,否则返回值2
            $(( a > 3 ? 10 : 0 ))(假设 a=5
            10
            代码示例
            📌
            关于运算符优先级的问题,建议还是通过 () 来进行区分(越内层括号内部的优先级越高),这样代码更易读而且记忆成本低,因此就不贴出运算符优先级了。
            条件判断语句
            简单的条件判断语句
            条件判断语句中判断语句的基本形式是为:[ condition ] 。注意 condition 条件的两侧有空格!!
            判断语句结合条件为:
            📌
            上述语句表达的含义为,当 condition 的结果为真时,执行表达式 A 或 B,如果为假则不执行。条件的真与假可以理解为 condition 运算式成立与不成立。
            condition 判断语句使用方法
            condition 如果是字符串,则相当于为真,能够执行 then 后面的表达式;
            condtion 如果是 [ ] 空(中括号中间至少应有 1 个空格),则相当于假,无法执行 then 后面的表达式;
            condition 如果为 0 ,也相当于为真,能够执行 then 后面的表达式;
            condition 如果为非零值,则相当于是假,无法执行 then 后面的表达式。
            💡
            上述关于数字的真假与其他编程语言中相反,其他语言中都是 0 为假,非零为真。这样反直觉的设定似乎与内部的状态码有关系,当 condition为真时,状态码为 0,当 condition 为假时,状态码为 1。
            下面的运算符验证可以不用在 .sh 文件中进行,可以直接在终端中执行,使用 if [ condition ]; then echo "A" ; fi 来进行验证,条件为真则输出 A,假则无输出。
            逻辑运算相关运算符
            📌
            逻辑运算相关的指令其实如果理解了英文含义就比较好懂,但如果还觉得难记其实也没关系,因为后面有更好用的方法进行逻辑判断,下一个部分会介绍。
            如果要进行逻辑判断,逻辑运算符需要使用下面的形式:
            -ltless than 的缩写,表示左侧小于右侧,如 [ 3 -lt 5 ] 为 真;
            -leless than or equal to 的缩写,表示左侧小于等于右侧,如 [ 5 -le 5 ] 为 真;
            -gtgreater than 的缩写,表示左侧大于右侧,如 [ 3 -gt 5 ] 为假;
            -gegreater than or equal to 的缩写,表示左侧大于等于右侧,如 [ 3 -gt 5 ] 为假;
            -eqequal to 的缩写,表示左侧等于右侧,如 [ 3 -eq 3 ] 为真;
            -nenot equal to 的缩写,表示左侧不等于右侧,如 [ 3 -ne 3 ] 为假。
            前面是数值的比较,后面介绍两个关于字符串比较的指令:
            = :用于判断左右两侧的字符串是否是相等的,如果相等则为真;
            != :用于判断左右两侧的字符串是否是不相等的,如果不相等则为真。
            文件权限、类型运算相关运算符
            -r :文件具有读的权限,如 [ -r hello.sh ]
            -w :文件具有写的权限,如 [ -w hello.sh ]
            -x :文件具有执行的权限,如 [ -x hello.sh ]
            -f :文件存在且是一个常规文件,如 [ -f hello.sh ],如果文件是一个目录,就为假 ;
            -d :文件存在且是一个目录,如 [ -d /home/tom/ ]
            条件判断的优化(优化逻辑判断)
            使用 [ condition ] 进行算数运算和逻辑判断,需要熟练掌握 -le -ge -eq 等运算符及其含义,有时候使用起来也比较麻烦,因此可以使用下面的方式进行:
            其中的 condition 可以使用 > < = 等运算符,比起前面的方式更适合进行比较运算。
            💡
            ((condition)) 相较于 [ condition ] ,进行算术运算和逻辑判断非常方便;
            [ condition ] 方法却不仅限于进行算术和逻辑判断,还可以用于进行文件类型、权限的判断,字符串比较等,可以说各有优缺点。
            条件分支语句
            二分支语句的使用:
            多分支语句的使用:
            简化版条件判断语句([ condition ] && 表达式A || 表达式B
            [ condition ] && 表达式A || 表达式B 语句的含义等同于下面的语句:
            表示的含义是,如果 condition 为真,则执行表达式 A,如果 condition 为假,则执行表达式 B。
            ⚠️
            [ condition ] && 表达式A || 表达式B 语句的形式有点类似于前面的三元表达式 条件 ? 值A: 值B ,它们的不同之处在于,前者是条件分支语句,后者是赋值表达式。
            前者用于在条件不同时执行不同的表达式,而后者用于在条件不同时给变量赋不同的值。
            case 语句
            case 语句长得会比较奇怪,至于为什么要这么设计,得问开发者当时是怎么想的,它的语法如下:
            📌
            上面语句的含义为,如果变量的值为 值 1,则执行表达式 1,如果为 值 2,则执行表达式2,以此类推,如果变量的值在 case 中没有值能够对应,就执行 *) 后面的表达式。
            case 语句中的 变量名 也可以替换为 $n ,如 $1$2 等,将输入的变量进行值的判断。
            循环语句
            for 循环
            for 循环有两种方式可以实现,第一种是标准格式,第二种是 C 语言风格的格式。
            标准格式:
            示例
            我觉得通过下面的示例对于 for 循环应该是比较容易理解的,如果大家看了下面的示例后还是云里雾里的,建议去学一学 python,入门比较快【python 笔记】。
            📌
            "$*" 使用时一定要加上引号,否则会被当作是 $@ 处理,即结果会一个一个输出,而非作为整体输出。
            C 语言风格的格式:
            关于这部分的代码,可以结合示例来理解,如果还是无法理解,那么最好去搜搜 C语言 的 for 循环部分教程。
            示例

            进一步地,求和示例:
            while 循环
            【回忆】[ condition ] 语句的回顾
            condition 如果是字符串,则相当于为真;
            condtion 如果是 [ ] 空(中括号中间至少应有 1 个空格),则相当于假;
            condition 如果为 0 ,也相当于为真;
            condition 如果为非零值,则相当于是假。
            💡
            上述关于数字的真假与其他编程语言中相反,其他语言中都是 0 为假,非零为真。这样反直觉的设定似乎与内部的状态码有关系,当 condition为真时,状态码为 0,当 condition 为假时,状态码为 1。
            逻辑运算相关运算符
            📌
            逻辑运算相关的指令其实如果理解了英文含义就比较好懂,但如果还觉得难记其实也没关系,因为后面有更好用的方法进行逻辑判断,下一个部分会介绍。
            如果要进行逻辑判断,逻辑运算符需要使用下面的形式:
            -ltless than 的缩写,表示左侧小于右侧,如 [ 3 -lt 5 ] 为 真;
            -leless than or equal to 的缩写,表示左侧小于等于右侧,如 [ 5 -le 5 ] 为 真;
            -gtgreater than 的缩写,表示左侧大于右侧,如 [ 3 -gt 5 ] 为假;
            -gegreater than or equal to 的缩写,表示左侧大于等于右侧,如 [ 3 -gt 5 ] 为假;
            -eqequal to 的缩写,表示左侧等于右侧,如 [ 3 -eq 3 ] 为真;
            -nenot equal to 的缩写,表示左侧不等于右侧,如 [ 3 -ne 3 ] 为假。
            前面是数值的比较,后面介绍两个关于字符串比较的指令:
            = :用于判断左右两侧的字符串是否是相等的,如果相等则为真;
            != :用于判断左右两侧的字符串是否是不相等的,如果不相等则为真。
            文件权限、类型运算相关运算符
            -r :文件具有读的权限,如 [ -r hello.sh ]
            -w :文件具有写的权限,如 [ -w hello.sh ]
            -x :文件具有执行的权限,如 [ -x hello.sh ]
            -f :文件存在且是一个常规文件,如 [ -f hello.sh ],如果文件是一个目录,就为假 ;
            -d :文件存在且是一个目录,如 [ -d /home/tom/ ]
            基本语法:
            示例:
             
            读取外部输入(read)
            read 是一个用于 从标准输入(或文件描述符)读取数据 的内置命令,可将输入内容赋值给变量。
            使用方法为 read [选项] 参数
            常用的选项有 -p-t 两种,前者用于指定提示用户输入的提示词,后者用于规定用户输入时间(默认以秒为单位)。参数用于指定用户输入的内容赋值给哪个变量。
            ⚠️
            需要注意 read 命令中,变量名必须放在所有选项之后,否则会导致语法错误。
            当我们想要输入的密码不可见时,可以使用 -s 参数。比如:
            自定义函数的使用
            函数的定义
            使用方法如下:
            代码示例:
            函数的传参与调用
            函数传递参数的方法与前面读取外部输入的方法类似,都是使用 $1 , $2 , $3 … 来表示传入的第几个参数,$@ 表示将传入函数的(多个)参数分散开,$# 表示传入函数的参数个数,$* 表示将传入函数的(多个)参数打包在一起,作为一个整体(字符串)。

            Ubuntu

            📝 Class Notes

            大家可以参照网上的教程或是韩老师的视频来安装 Ubuntu 并设置中文。Ubuntu 中的指令大体上和 CentOS 是一样的,因此学习了前面的 CentOS 指令上手也很快。
            在 Ubuntu 中,python 是默认安装的,原生支持 python 的各种操作。
            一个小小的注意事项(Ubuntu 安装后)
            在 Ubuntu 安装后,会有一个弹窗询问你设置的语言、键盘格式等等,有一个窗口是询问我们将 Ubuntu 安装到电脑上还是使用 Ubuntu 进行测试。这里一定要选择将 Ubuntu 安装到电脑上,如果使用 测试的版本,那么后面对 Ubuntu 进行的所有修改在重启后都会清零,而且系统测试版会很卡。
            设置 root 用户初始密码
            ubuntu 第一次登录时 root 用户是没有密码的,因此需要为 root 用户初始化密码。
            右键桌面打开终端,在终端中输入 sudo passwd 设置 root 用户的初始密码(第一次),该操作也可以用于后续修改 root 用户的密码。
            设置完密码后,可以通过 su root 指令切换到当前用户为 root 用户,拥有相关的 root 权限,切换后输入 exit 可以退出,变更用户为普通用户。
            镜像网站的设置
            Ubuntu 使用的是 APT 进行包的下载、管理和更新的,由于 Ubuntu APT 源的服务器分布在国外,因此在国内管理这些包有时候会不方便(网络问题)。因此需要为 APT 配置镜像源,比如将 APT 的镜像源配置为清华大学,这样,再通过 APT 指令下载和管理包就会快很多。
            💡
            建议大家在配置镜像源之前,先将当前的 Ubuntu 系统备份一份。
            我的 Ubuntu 版本是 24.04.02,在这个版本中,Ubuntu 默认已经为我们配置好了国内镜像源(官方配置的一个镜像源),但可能不如国内高校或企业的镜像源稳定,因此大家可以按需进行更换。
            如何查看 Ubuntu 是否配置了国内镜像源
            可以通过 cat /etc/apt/sources.list.d/ubuntu.sources (视频中采用 cat /etc/apt/sources.list 指令,新版位置已经迁移了)先查看当前安装的 Ubuntu 的镜像源是什么,如果出现的网址是以 cn. 开头的,那么说明 Ubuntu 是默认帮我们设置好了的。
            notion image
            国内镜像源的配置过程中有很多注意点,大家直接最好跟着 韩老师的视频 进行操作。
            Ubuntu 软件包相关指令(apt)
            apt 是新一代的包管理指令,整合了 apt-getapt-cache 等指令,用起来更加方便。
            apt 和传统指令的对照
            操作
            apt 命令
            apt-get 等效命令
            安装包
            apt install <包名>
            apt-get install <包名>
            卸载包(保留配置)
            apt remove <包名>
            apt-get remove <包名>
            卸载包(删除配置)
            apt purge <包名>
            apt-get purge <包名>
            更新包索引
            apt update
            apt-get update
            升级所有包
            apt upgrade
            apt-get upgrade
            升级并处理依赖冲突
            apt full-upgrade
            apt-get dist-upgrade
            搜索包
            apt search <关键词>
            apt-cache search <关键词>
            显示包信息
            apt show <包名>
            apt-cache show <包名>
             
            查询相关:
            指令
            作用
            示例
            apt search <关键词>
            根据关键词搜索软件包
            apt search python3
            apt show <包名>
            显示软件包的详细信息(版本、依赖等)
            apt show openssl
            apt list --installed
            列出所有已安装的软件包
            apt list --installed | grep
            apt list --upgradable
            列出可升级的软件包
            apt list --upgradable
            软件包更新、安装、卸载相关:
            指令
            作用
            示例
            sudo apt update
            更新软件包列表(同步最新仓库信息)
            sudo apt update
            sudo apt upgrade
            升级所有可升级的软件包
            sudo apt upgrade
            sudo apt install <包名>
            安装指定软件包
            sudo apt install nginx
            sudo apt remove <包名>
            卸载软件包(保留配置文件)
            sudo apt remove firefox
            sudo apt purge <包名>
            卸载软件包并删除配置文件
            sudo apt purge mysql-server
            sudo apt autoremove
            自动删除不再需要的依赖包
            sudo apt autoremove
            Ubuntu 安装 vim
            为什么要安装 vim 而不使用 Ubuntu 自带的 vi
            Ubuntu 默认安装的是 vim 的精简版(vim-tiny),而 vi 命令会指向 /usr/bin/vim.tiny
            此时,vi 和 vim 调用的实际上是同一个程序,但 vim.tiny 是功能受限的版本。
            vi 和 vim 的对比如下:
            功能
            vim.tiny(默认 vi
            完整版 vim
            语法高亮
            ❌ 不支持
            ✅ 支持
            多窗口编辑
            ❌ 不支持
            ✅ 支持
            插件支持
            ❌ 不支持
            ✅ 支持
            脚本扩展(.vimrc)
            ❌ 不支持
            ✅ 支持
            命令行历史
            ❌ 不支持
            ✅ 支持
            鼠标操作
            ❌ 不支持
            ✅ 支持
            通过 sudo apt install vim 指令即可成功安装 vim ,如果要卸载 vim,可以通过 sudo apt remove vim ,利用 sudo apt show vim 可以查询 vim 的相关信息。
            Ubuntu 的远程登录
            在实际工作中,与 CentOS 一样,Ubuntu 也是在一个集群中进行工作的,我们常常会需要登录到他人的 Ubuntu 中进行操作,因此,就需要远程登陆。
            远程登录需要利用到 SSH 服务(Secure Shell 的缩写,是一种网络安全协议,几乎所有的 Unix/Linux 平台都可以使用),默认占用 22 号端口,Ubuntu 默认是没有 SSH 服务的,也就是说无法实现远程登录。
            要想配置 SSH 服务,需要安装客户端和服务器。 如果, A 机器想被 B 机器远程控制,那么, A 机器需要安装 SSH 服务器, B 机器需要安装 SSH 客户端,下面我们需要据此进行配置。
            在配置远程登录之前,我们可以先验证下 Ubuntu 是否有监听 22 号端口。先通过 sudo apt insatll net-tools 安装网络工具,然后通过 netstat -anp | more 指令即可查看是否存在 22 号端口。
            在 state 处于 LISTEN 状态的地址中没有找到 22 号端口,因此需要进行 SSH 服务的配置。
            通过 sudo apt install openssh-server 指令即可安装 SSH ,并配置相应的 SSHD 服务。此时再通过 netstat -anp | more 指令即可查询到 22 号端口(如下图所示)。
            notion image
            此时,我们可以使用 ifconfig 来查看 Ubuntu 的 IP 地址,并在 Xshell 中进行配置并登录,这样就实现了在 Xshell 远程登录 Ubuntu。

            如果我们想要实现两台 Ubuntu 系统的远程登录,可以先备份一份当前的 Ubuntu 系统(或者克隆)用于测试。
            将虚拟机中的两个 Ubuntu 都打开并进入终端页面,分别通过 ifconfig 查看其 IP 地址(比如 Ubuntu A 的地址为 192.168.200.129,Ubuntu B 的地址为 192.168.200.130),在 A 中输入 ssh 用户名@IP地址 (如 ssh df@192.168.200.130),输入 yes 即另一台设备用户的密码后即可登录到另一台设备。
            如果要从设备中登出,可以通过 logout 指令或 exit 指令来实现。

            可能遇到的问题:
            如果之前你曾尝试过登录其他用户且密码输错了多次或是其他什么操作,导致使用 ssh df@192.168.200.130 指令时出现 下图所示的报错:
            notion image
            可以在报错的文本中找到图中绿框部分的语句,将其选中,鼠标右键复制并粘贴到终端中,执行后即可解决问题。

            日志管理

            📝 Class Notes

            什么是日志?
            日志文件是重要的系统记录文件,能够追踪系统的行为、排查错误、监督用户、分析系统性能等。
            Linux 的日志通常存放在 /var/log 目录下,我们通过 cd /var/log 进入该目录后,通过 ll 即可查看所有的日志文件。
            常用的日志文件
            日志文件路径
            说明
            查看命令
            /var/log/boot.log
            系统启动日志,记录内核初始化、服务加载和硬件检测过程
            catless
            /var/log/cron
            定时任务日志,追踪 crontab 任务的执行状态及错误
            tail -fgrep
            /var/log/lastlog
            所有用户最后一次登录时间(二进制文件)
            lastlog
            /var/log/mail
            邮件系统日志,记录 Postfix/Dovecot 等邮件服务的收发和错误事件
            grep 'error' /var/log/mail
            /var/log/messages
            系统核心日志,涵盖内核、网络、服务等关键事件(重点故障排查目标)
            tail -n 50 (显示最后 50 行)
            /var/log/secure
            安全审计日志,记录 SSH 登录、sudo 授权、密码修改等敏感操作
            grep 'Failed'
            /var/run/utmp
            当前在线用户信息(二进制文件),动态更新
            wwhousers
            /var/log/cups/
            打印服务日志,记录 CUPS 打印系统的设备连接和作业状态
            cat access_log
            /var/log/dmesg
            内核自检日志,包含开机时硬件检测和驱动加载信息(同步查看指令)
            dmesg | less
            /var/log/btmp
            记录错误登录尝试(二进制文件)
            lastb
            /var/log/wtmp
            永久用户登录记录(二进制文件),包含登录/注销、重启/关机事件
            last
            rsyslogd 日志管理服务
            rsyslogd 是 Linux 系统中最核心的 日志管理服务,负责收集、分类、存储和转发系统及应用程序生成的日志,将这些日志放入前面介绍的日志文件中。
            具体的分类规则记录在 /etc/rsyslog.conf/etc/rsyslog.d/*.conf
             
            配置文件
            定位与作用
            加载顺序
            /etc/rsyslog.conf
            主配置文件:定义全局参数、基础模块、默认日志规则(如系统级日志存储路径)。
            优先加载
            /etc/rsyslog.d/*.conf
            自定义片段:用于扩展或覆盖主配置(如为特定服务添加日志规则)。
            后续加载
             
            上述配置文件中,主配置文件一般不进行修改,如果我们想要添加自定义配置,最好是在 .d/ 目录自定义管理规则。
            查看 rsyslogd 是否自启动:systemctl is-enabled rsyslogsystemctl list-unit-files | grep rsyslog
            查看当前 rsyslogd 是否启动: ps aux | grep "syslog | grep -v grep .

            规则的记录语法为:Facility.Priority Target (如下图中红框部分所示)。
            notion image
            下面来解释一下 Facility PriorityTarget 三项内容如何理解:
            Facility (用于定义日志生成来源):
            Facility 名称
            说明
            auth / authpriv
            认证日志(如用户登录、sudo 操作),存储 /var/log/secure 或 /var/log/auth.log
            cron
            定时任务日志(crontab 执行记录),对应 /var/log/cron
            kern
            内核日志(硬件驱动、内核错误),对应 /var/log/kern.log
            mail
            邮件服务日志(Postfix、Dovecot),对应 /var/log/mail.log
            syslog
            rsyslogd 自身的运行日志。
            user
            用户级应用程序日志(默认 Facility)。
            local0 ~ local7
            自定义 Facility(供第三方应用使用,如 Nginx 可配置为 local0)。
            *
            表示接受来自 所有来源 的日志。
            Priority (按日志严重性划分级别):
            从第一个到最后一个,优先级由低到高。
            Priority 名称
            说明
            *
            表示接受该 Facility 所有级别的日志,等同于 debug。
            debug
            调试信息,日志通信最多。
            info
            常规运行信息(如服务启动成功),最常用。
            notice
            需要注意但非错误的事件(如磁盘剩余空间不足 20%),最具重要性的普通条件信息。
            warning
            潜在问题警告(如网络接口丢包)。
            err
            运行时错误(如配置文件语法错误),阻止某个功能或模块不能正常工作的信息。
            crit
            严重错误(如硬件故障导致服务终止),阻止整个系统或整个软件不能正常工作的信息。
            alert
            需立即处理或修改的紧急事件(如系统温度过高)。
            emerg
            系统不可用(如内核崩溃)。
            none
            什么都不记录。
            关于优先级要有这样的直觉:低优先级的任务记录的内容多,记录频率高,因此占用内存也大,通常是常规操作;而高优先级的任务记录的内容少,记录频率低,用于快速定位核心问题所在。
            Target (存储/转发目标):
            • 文件路径:如 /var/log/messages
            • 远程服务器:@192.168.1.100:514(UDP)或 @@192.168.1.100:514(TCP)。
            • 用户终端:root(发送到 root 用户的终端)。
            日志文件中的单条日志解读
            日志文件中记录的信息大体上都符合这个规则: <优先级>时间戳 主机名 服务名[进程ID]: 事件信息 (其中优先级进程 ID 不一定会有)。
            如下面这条日志:
            字段
            说明
            优先级
            <134>:包含 Facility(authpriv)和 Priority(err)的数值编码。
            时间戳
            Apr 15 10:00:00:事件发生的本地时间(格式可配置)。
            主机名
            web01:生成日志的主机名(本地日志可能省略)。
            服务名
            sshd:产生日志的程序或服务名称。
            进程ID
            [1234]:进程的 PID(可选,部分服务可能不显示)。
            事件信息
            Failed password...:具体事件描述(自由文本或结构化数据)。
            logrotate 日志轮替
            为了避免日志文件越来越多(很久以前的日志文件对现在没有什么帮助),需要使用 logrotate 自动将日志删除。
            logrotate 是 Linux 系统中用于 自动化日志管理 的核心工具,主要 日志轮转(切割)、压缩删除旧日志邮件通知等。
            功能
            说明
            日志轮转
            按时间(日/周/月)或文件大小切割日志,避免单个日志文件过大。
            压缩旧日志
            对轮转后的旧日志进行压缩(支持 gzip/bzip2/xz 等格式),节省磁盘空间。
            删除过期日志
            自动清理超过指定数量的旧日志文件。
            邮件通知
            将删除的日志通过邮件发送给管理员。

            logrotate 的配置文件:
            notion image
            • /etc/logrotate.conf (文件):全局默认配置;
            • /etc/logrotate.d/(目录):存放各应用程序的独立配置。
            一般建议在 /etc/logrotate.d/ 目录中添加文件进行配置,这样方便日志功能的管理,/etc/logrotate.conf 文件中是全局生效的配置。

            /etc/logrotate.conf 或是在 /etc/logrotate.d/ 目录的文件中进行配置时,需遵循以下的语法:
            下面来说明全局参数和块内参数的选择:
            指令
            说明
            示例
            daily/weekly/monthly
            按日/周/月轮转日志(默认按需轮转,需手动触发)。
            daily
            rotate N
            保留最近 N 次轮转的旧日志文件。
            rotate 30 (保留最近 30 次的日志)
            size SIZE
            当日志文件达到指定大小时触发轮转(如 size 100Msize 2G)。
            size 200M
            dateext
            使用日期作为旧日志后缀(格式:-YYYYMMDD)。
            dateext
            missingok
            如果日志文件不存在,忽略错误继续执行。
            missingok
            notifempty
            not if empty 空文件不进行轮转。
            notifempty
            copytruncate
            复制日志内容到新文件后清空原文件(避免重启服务)。
            copytruncate
            prerotate/endscript
            轮转前执行自定义脚本。
            postrotate/endscript
            轮转后执行自定义脚本(如通知服务重载)。
            sharedscripts
            所有日志轮转完成后仅执行一次 postrotate 脚本(默认每个日志执行一次)。
            sharedscripts
            compress
            压缩上一次生成的日志文件(默认使用 gzip,生成 .gz 文件)。
            compress
            delaycompress
            延迟压缩上一次轮转的日志(避免压缩正在被写入的文件)。
            delaycompress
            create MODE OWNER GROUP
            轮转后创建新日志文件并指定权限、属主和属组。
            create 0640 nginx adm
            💡
            在没有使用 dateext 指令时,文件默认生成的形式为 .log .log.1 , .log.2 , .log.3 等等,当有新文件生成时,原先的 .log 文件会变更为 .log.1 ,原先的 .log.1 会变更为 .log.2 以此类推。
            示例:
             
            日志轮替的原理
            日志轮替实际上是通过定时任务 crond 服务触发的。可以在 /etc/cron.daily/ 目录中看到 logrotate 文件。
            notion image
            journalctl
            该指令是 systemd 日志管理系统的专用工具,用于查看和分析 二进制格式的系统日志rsyslogd 为纯文本)。默认情况下,journalctl(由 systemd-journald 管理)的日志存储在内存中,若未配置持久化存储,系统重启后这些日志会被清空
            是否启用持久化存储和 Linux 的发行版有关。一般来说,可以通过以下两点来判断 jornalctl 是否启用了持久化存储:
            • 内存存储:若系统 未创建 /var/log/journal/ 目录,日志默认保存在 /run/log/journal/(内存中),重启后丢失
            • 磁盘存储:若系统 存在 /var/log/journal/ 目录,日志会持久化到磁盘,重启后保留
            也就是说,如果我们手动创建了 /var/log/journal 目录,那么就相当于开启了 journalctl 的持久化存储。

            对于 CentOS 系统而言:
            • CentOS 7:默认 不启用 持久化存储,需手动创建 /var/log/journal/
            • CentOS 8/9:默认 启用 持久化存储,无需额外配置。

            journalctl 的常用指令如下:
            基础指令:
            指令
            功能说明
            journalctl
            查看全部日志(从旧到新显示)
            journalctl -e
            跳转到日志末尾(显示最新内容)
            journalctl -n <行数>
            查看最近 N 行日志(默认 10 行)
            journalctl -k
            仅显示内核日志
            journalctl -b
            查看当前启动周期的日志
            journalctl -b -0
            查看本次启动的日志(同 -b
            journalctl -b -1
            查看上一次启动的日志
            journalctl --list-boots
            列出所有启动记录(编号、时间、启动ID)
            跟踪相关指令:
            指令
            功能说明
            journalctl -f
            实时跟踪最新日志(类似 tail -f
            journalctl -u <服务名>
            查看指定 systemd 服务的日志
            journalctl _PID=<进程ID>
            按进程 PID 过滤日志
            journalctl _UID=<用户ID>
            按用户 UID 过滤日志
            journalctl -p <优先级>
            按日志优先级过滤(如 errinfodebug
            journalctl --since <时间>
            查看从指定时间开始的日志(如 "2024-01-01 09:00:00"
            journalctl --until <时间>
            查看截止到某时间的日志(如 "2 hours ago"

            定制自己的 Linux 系统

            在开始定制自己的 Linux 系统前,最好先保存一份当前系统的快照,避免操作错误,未来重装系统。
            为什么要定制 Linux 系统?
            定制 Linux 系统主要是为了从特定需求出发,减小系统开销,移除冗余部件,让系统只实现某一个或某一类特定的功能。
            定制 Linux 系统一方面可以节省内存(内存可压缩至 100 MB 以内),另一方面也可以提升系统安全性,降低系统被攻击的风险(攻击面减小了)。
            也就是说,当我们为了实现某个小的功能而使用 Linux 系统时,很多功能实际上是我们不需要的,我们可以对原先庞大的 Linux 系统进行裁剪,修补出我们想要的样子。
            目前定制 Linux 系统在嵌入式系统中应用比较广泛,也有人专门讲授嵌入式 Linux 系统的相关内容。
            【知识回顾】🌟 新增硬盘并实现分区挂载
            分区和挂载的简单理解
            在 Linux 系统中,分区(Partition) 是将物理硬盘划分为多个逻辑存储单元的过程。每个分区可以独立管理、格式化和挂载,用于存储文件或实现特定功能(如交换空间)。
            由于 Linux 中万物皆目录,因此 Linux 的分区需要使用 Linux 的文件系统来表示的。当我们在 Linux 中添加硬盘并分区后,需要将硬盘挂载到 Linux 文件系统中。这样,当我们对文件目录进行操作时,物理硬盘中也会进行相应的变化,比如添加文件。
            一般,物理硬盘需要经过 分区 → 格式化 → 挂载 的逻辑操作,才能整合到 Linux 文件系统中,其中挂载是连接物理存储和逻辑目录树的核心步骤,使分区内容可通过目录访问。
            通过老师的这幅图也能够比较好理解:
            notion image
            Linux 硬盘说明
            Linux 中的硬盘主要有 IDE 硬盘(Integrated Drive Electronics,即集成驱动器电子设备)和 SCSI 硬盘(Small Computer System Interface,即小型计算机系统接口)两种,IDE 是早期个人电脑的主流接口,目前主要使用的是 SCSI 硬盘。
            IDE 驱动器标识符(了解即可)
            IDE 的驱动器标识符为 hdx~ ,需要分为三个部分来看。
            • 第一部分为 ”hd”,表示该标识符为 IDE 驱动器标识符;
            • 第二部分为 “x”,表示的是盘号。x 是一个泛指,可以取 a, b, c, d 这四个值。
              • a 表示基本盘,是第一个 IDE 通道的主设备(Primary Master);
              • b 表示基本从属盘,是第一个 IDE 通道的从设备(Primary Slave);
              • c 表示辅助主盘,是第二个 IDE 通道的主设备(Secondary Master);
              • d 表示辅助从属盘,是第二个 IDE 通道的从设备(Secondary Slave)。
            • 第三部分为 “~”,表示的是分区。~ 也是一个泛指,取值为数字。
              • 1~4 表示的是主分区或扩展分区;
              • 5 开始往后是逻辑分区

            比如,hda1 表示的是 IDE 基本盘的分区 1hdd4 表示的是 IDE 辅助从属盘的分区 4.
            SCSI 硬盘标识符
            SCSI 硬盘标识符使用 sdx~ 表示,需要分为三个部分来看。
            • 第一个部分为 “sd ”,表示该标识符为 SCSI 硬盘标识符;
            • 第二个部分为 “x”,表示的是盘号。只不过与 IDE 不同,不限于 a, b, c, d 四个取值。规则如下:
              • 按检测顺序分配:字母从 a 开始,根据系统检测到设备的顺序递增。
              • 无物理通道限制:支持任意数量设备(理论上可达 sdz 甚至更多,取决于控制器能力)。
              • 无主从关系:SCSI 设备通过唯一 ID 识别,无需主/从跳线配置。
            • 第三个部分为 ”~”,表示的是分区。~ 也是一个泛指,取值为数字。
              • 1~4 表示的是主分区或扩展分区;
              • 5 开始往后是逻辑分区

            比如,sda1 表示的是 SCSI 硬盘 a 的分区 1。
            lsblklsblk -f 指令
            lsblk 是 list block devices 的缩写。
            用于列出所有块设备,查看所有设备的挂载情况。
            在终端中输入 lsblk 指令后,输出结果中各项的含义(下面左侧部分为输出的代码,右侧为各列的含义说明):
             
            列名
            说明
            NAME
            设备名称(如 sda 表示第一块硬盘,sda1 表示其第一个分区)。
            MAJ:MIN
            设备的主设备号(Major)和次设备号(Minor),用于内核识别设备(见下文示例)。
            RM
            是否为可移动设备(Removable)。1 表示可移动(如 U 盘),0 表示固定设备。
            SIZE
            设备或分区的总容量(如 20G 表示 20GB)。
            RO
            是否为只读设备(Read-Only)。1 表示只读(如光盘),0 表示可读写。
            TYPE
            设备类型。disk:物理硬盘;part:分区;rom:光盘等。
            MOUNTPOINT
            分区的挂载点(如 / 表示根分区,/boot 表示启动分区,空表示未挂载)。
            在终端中输入 lsblk -f 指令后,输出结果中的各项含义(下面左侧部分为输出的代码,右侧为各列的含义说明):
            列名
            说明
            NAME
            设备名称(如 sda1 表示第一块硬盘的第一个分区)。
            FSTYPE
            文件系统类型(如 ext4xfsswapvfat,未格式化则为空)。
            LABEL
            文件系统的卷标(用户自定义的标识符,如 BOOTDATA)。
            UUID
            文件系统的唯一标识符(Universally Unique Identifier),用于可靠识别设备。
            MOUNTPOINT
            分区的挂载路径(如 / 表示根目录,[SWAP] 表示交换分区)。
            🌟 如何增加一块新硬盘并实现挂载
            在进行新硬盘挂载前,建议大家保存一份快照,以免后续操作错误时无法恢复。
            具体的步骤如下:
            1. 虚拟机添加新硬盘;
            1. 磁盘分区;
            1. 格式化硬盘(分区内创建文件系统);
            1. 挂载(将硬盘分区系统链接到 Linux 文件系统);
            1. (设置自动挂载)。
            💡
            看到弹幕中有很多人因为增加了新硬盘导致 vmware 或 centos 需要重装,但我按照老师的步骤来是没有出错的。因此建议大家先看完老师的操作后再按照笔记中的步骤来。出错的原因也有可能是系统问题,我是在 windows vmware 虚拟机下操作的,没有问题,可能其它系统会有其他细节。
            添加新磁盘的步骤(图片)
            notion image
            notion image
            notion image
            notion image
            notion image
            📌
            添加完新磁盘后,需要重启虚拟机,在终端中输入 reboot 即可重启。重启后在终端中输入lsblk 即可查看到刚刚创建的磁盘 sdb ,但磁盘中还没有进行分区。
            (磁盘默认是添加到 /dev/ 目录下的,过去曾经介绍过,/dev/ 用于存放磁盘目录)
            磁盘分区
            在终端中输入 fdisk /dev/sdb 指令后,输入 m ,即可进入到磁盘修改页面,在这个页面中可以对磁盘进行分区。
            在这个页面中,有以下这些指令可供选择(页面中是英文的):
            m
            显示命令列表
            p
            显示磁盘分区 同 fdisk –l
            n
            新增分区
            d
            删除分区
            w
            写入并退出
            q
            不写入直接退出
            我们需要输入 n 新增一个分区,然后输入 p 选择分区类型为主分区,之后就一直按下回车,保持默认设置即可。
            在最后又会回到先前显示指令的页面中,按下 w 即可保存并退出(如果输入 q 会不保存直接退出)。
            格式化硬盘
            在终端中输入指令 mkfs -t ext4 /dev/sdb1 即可将硬盘 sdb 中的第一个分区 sdb1 格式化为 ext4 文件系统(如果创建了多个分区,那么就需要进行多个分区的格式化,注意 /dev/sdb1 这个名称需要依据你想要格式化的分区来写,由于之前我们就只创建了一个分区,因此只需要执行一次)。
            其中 mkfs 是 "make file system" 的缩写,直译为 “创建文件系统”。它的作用是将一个分区或存储设备格式化为特定的文件系统(如 ext4、XFS、swap 等),使其能够被操作系统读写和管理。
            ext4XFSswap 三个文件系统的含义:
            • 常规用途ext4(稳定性好,适合个人/服务器)。
            • 大文件/高并发XFS(性能更优,支持日志恢复)。
            • 交换空间swap(需通过 mkswap 和 swapon 激活)
            挂载/取消挂载
            挂载是将分区与 Linux 文件系统中的文件目录联系起来,因此我们需要现有一个可供挂载的目录。一般是在根目录下创建一个文件目录进行挂载。
            挂载使用的指令是 mount 分区路径 挂载目录 。比如 mount /dev/sdb1 /newdisk ,其中 sdb1 就是我们先前创建的分区,这条指令的意思是将 sdb1 这个分区挂载到 /newdisk 目录下,也就是将物理磁盘和文件目录关联。
            如果要取消挂载,可以使用 umonut 挂载目录umount 分区路径 指令,如 umount /newdiskumount /dev/sdb1
            📌
            挂载与取消挂载时需要注意,我们手动挂载的目录默认是只在本次运行期间有效,重启系统后原来挂载的指令会失效。
            如果想要在重启后,保持先前磁盘分区的挂载状态,需要进行自动挂载的设置;
            同理,如果我们通过自动挂载将目录与磁盘分区绑定了,取消挂载的指令也只在本次运行期间有效,重启后失效。
            自动挂载
            要实现自动挂载需要我们手动操作 /etc/fstab 文件,具体的过程如下:
            1. vim /etc/fstab 打开有关挂载的配置文件;
              1. 文件中各列的含义
                notion image
                列数
                字段
                含义
                示例解析
                第 1 列
                文件系统标识
                设备路径(如 /dev/sdb1)或分区的 UUID
                使用设备名 /dev/sdb1(建议改用 UUID,避免设备名变化导致挂载失败)。
                第 2 列
                挂载点
                文件系统挂载到的目录(必须是已存在的空目录)。
                挂载到 /newdisk 目录。
                第 3 列
                文件系统类型
                分区的文件系统类型(如 ext4xfsswap)。
                分区格式化为 ext4 文件系统。
                第 4 列
                挂载选项
                挂载时使用的选项(多个选项用逗号分隔)。
                defaults 表示默认选项:rw,suid,dev,exec,auto,nouser,async
                第 5 列
                dump 备份标志
                是否允许 dump 工具备份(0 表示禁用,1 表示启用)。
                0 表示不备份此分区。
                第 6 列
                fsck 检查顺序
                系统启动时检查文件系统的顺序(0 表示不检查,根分区通常设为 1)。
                0 表示不检查此分区(非系统关键数据盘可设为 0,根分区建议设为 1)。
            1. 按照前面学习的 vim 编辑器的使用方法,将光标移动到第一行 UUID,键盘按下 yy 复制该行,然后再按下 p 在该行上方粘贴;
            1. 然后将该行的 UUID=… 一列替换为新分区的名称 /dev/sdb1 ,将挂载路径更改为 /newdisk ,将最后两列数字改为 0 后,esc 退出编辑,输入 冒号 :wq 保存退出。
              1. 当然,也可以通过 lsblk -f 指令查看新添加的磁盘分区的 UUID,将其复制后作为第一列的值。
            notion image

            完成上面的编辑操作后,在终端中继续输入 mount -a 即可立刻生效更改(或者也可以通过 reboot 指令重启后生效)。
            ‼️ 开始定制 Linux 系统前 —— 移除旧硬盘(sdb)【包含系统移除硬盘后无法开机的问题求解】
            这部分最好看看,避免后面系统打不开。
            正常步骤 —— 先取消自动挂载,然后移除硬盘(未设置自动挂载的直接移除硬盘)
            在定制 Linux 系统前,我们需要先将当前 CentOS 下的其他硬盘都移除,只保留 sda 盘以方便后续操作。
            还记得我们过去在硬盘挂载的那部分课程中添加的硬盘 sdb 吗?
            如果当时你设置了自动挂载模式,也就是在 /etc/fstab 中添加了硬盘 sdb,那么,你需要先进入 Linux 系统,打开终端,通过 vim /etc/fstab 指令将有关 sdb 硬盘挂载的语句删除。如果当时你没有设置自动挂载模式,那么,不用通过 vim /etc/fstab 打开配置文件,直接进行硬盘移除操作即可(如果不确定自己是否设置了自动挂载,还是需要通过 vim /etc/fstab 查看是否有一条关于 sdb 硬盘的记录,有的话删除)。
            notion image
            然后,将 Linux 系统关机,右键 CentOS 虚拟机打开设置,在设置中按照下图所示步骤移除硬盘:
            notion image
            问题 —— 如果设置过自动挂载,但现在直接移除硬盘(未取消自动挂载)
            这个问题会导致系统一直处在开机状态,不断加载,无法进入系统,因为我们设置了自动挂载语句,而系统却找不到对应的硬盘区域,所以有这个问题。
            解决这个问题有两种方法:
            ① 如果你在最开始创建 Linux 系统时设置过快照,直接通过快照回到系统初始状态即可,相当于是系统初始化了;
            要注意,快照只会保存数据信息,不会保存硬盘信息,因此移除硬盘后不会恢复之前的硬盘。
            ② 进入紧急模式,删除自动挂载语句。

            下面着重介绍第二个解决方法:
            1. 开机,在开启页面按下 e 进入编辑页面。这一步与找回 root 密码是类似的;
            1. 在编辑页面中使用键盘上的 “向下方向键 ↓” 将光标向下移动,找到以 linux16 开头的段落,在段落的末尾输入 emergency 进入紧急模式;
              1. notion image
            1. 输入 root 用户的密码进入编辑状态;
              1. notion image
            1. 在终端中输入指令 mount -o remount,rw / 将文件设置为可编辑的模式,否则在后续进行修改配置文件操作时会报错:该文件是 readonly 的;
            1. 在终端中输入指令 vim /etc/fstab 进入硬盘配置文件,此时会出现下图所示的提示信息,我们输入 e 进入 edit 编辑状态;
              1. notion image
            1. 在配置文件的第一行可以看到我们先前设置 sdb 为自动挂载的语句,按下 i 进入编辑模式,然后删除第一行语句后按下 esc ,再输入 :wq 保存并退出;
              1. notion image
            1. 此时,我们的工作就完成了,在终端中输入 reboot 重启即可。
            开始定制 Linux 系统前 —— 了解 Linux 系统的启动流程
            下面的步骤在第一次阅读时一般是看不懂的,在后面进行定制 Linux 步骤时可以回过头来与下面的步骤对应,慢慢就能够理解了。
            1、 首先 Linux 要通过自检, 检查硬件设备有没有故障;
            2、 如果有多块启动盘的话, 需要在 BIOS 中选择启动磁盘;
            3、 启动 MBR 中的 bootloader 引导程序;
            4、 加载内核文件;
            5、 执行所有进程的父进程 systemd;
            6、 欢迎界面;

            定制 Linux 系统的主要步骤
            定制 Linux 系统的过程一定一定要细心,刚开始配置时按照下面的过程做一步,再看一步。
            🌟 定制过程的流程图
            由于交换分区并不是必须的,因此创建 min_Linux 系统时没有设置交换分区。
            notion image
            1. 添加用于定制化 Linux 系统的硬盘(空间无需太大);
            1. (新添加硬盘的)磁盘分区与分区格式化操作;
            1. 创建目录,将磁盘分区与 Linux 文件目录进行挂载;
            1. 安装 grub2 内核文件;
            1. 将所需启动文件迁移到先前创建的文件目录中;
            1. grub 配置文件的修改;
            1. 创建目标根文件系统并迁移需要的指令和库文件;
            1. (开始定制!!)利用前面的 sdb 硬盘创建 min_Linux 最小系统;

            添加新硬盘
            这一步最好将 Linux 系统关机后进行。
            notion image
            由于后续的操作中,磁盘的大小不需要特别多,因此这里只设置为 2GB.
            由于后续的操作中,磁盘的大小不需要特别多,因此这里只设置为 2GB.
            ⚠️
            一定要注意:选择 “将虚拟磁盘存储为单个文件”。
            重命名硬件磁盘(这是为了在后续更好区分出这个磁盘文件)。
            notion image
             
            硬盘分区与格式化
            硬盘分区:
            添加完硬盘后,开机(或重启)Linux 系统,在终端中,通过 lsblk 指令查看添加新硬盘后 Linux 的磁盘情况:
            notion image
            从图中可以看到,Linux 新添加了 sdb 硬盘。
            接下来要进行的工作就是对 sdb 硬盘进行分区了,在终端中输入 fdisk /dev/sdb (根据你新添加的硬盘名称而定),然后再输入 m 进行指令页面:
            notion image
            下面进行磁盘的第一个分区设置,将第一个分区设置为 +500M 的大小(磁盘大小的设置在 Linux 信息中亦有提示,+size{K,M,G}):
            notion image
            接着进行磁盘的第二个分区设置,将剩余的内存全部分配给第二个分区:
            notion image
            最后一定要记得使用 w 写入,而非使用 q 退出,后者不会进行保存。

            硬盘格式化:
            添加分区后,再执行 lsblk 即可看见硬盘 sdb 下多出了两个分区:
            notion image
            首先进行 sdb1 的格式化,在终端中输入 mkfs -t ext4 /dev/sdb1 即可进行 sdb1 分区的格式化;
            接着进行 sdb2 的格式化,在终端中输入 mkfs -t ext4 /dev/sdb2 即可进行 sdb2 分区的格式化。
            磁盘挂载
            在挂载之前,需要确定磁盘需要挂载到哪个目录下。
            由于我们需要定制 Linux 最小系统,因此我们需要专门创建两个文件目录,一个文件目录用于存放指令,一个文件目录用于存放其他文件。两个目录分别对应先前创建的两个分区。
            通过 mkdir -p /mnt/boot /mnt/sysroot 指令创建两个空目录用于挂载。
            首先进行目录一的挂载,mount /dev/sdb1 /mnt/boot
            接着进行目录二的挂载,mount /dev/sdb2 /mnt/sysroot
            📌
            如果不小心挂载错了就重启一下 Linux 系统,因为此时还没有进行自动挂载操作,因此前面两条指令进行的挂载都只是临时性的挂载。
            安装内核文件
            这一步安装内核文件是为了后面移植 Linux 系统做准备,每个 Linux 系统的启动都需要内核文件支持。
            通过 grub2-install --root-directory=/mnt /dev/sdbGRUB 2 引导加载程序安装到指定磁盘 /dev/sdb 的 主引导记录(MBR) 中,并指定目标系统的根文件系统挂载点为 /mnt(该指令无需记忆,需要时采用即可)。
            notion image
            可以通过 hexdump -C -n 512 /dev/sdb 指令来进一步验证内核文件是否安装成功。
            notion image
            如果显示上图的十六进制码,就说明是安装成功了。
            拷贝并迁移启动文件
            通过 \cp -rf /boot/* /mnt/boot/ 语句(\cp可以同时实现覆盖操作)将 /boot 目录下的所有启动文件拷贝到 /mnt/boot 目录(也就是 sdb1 分区)中。
            grub 配置文件的修改
            这一步的目的是为了后续将 sdb 作为最小启动系统的启动盘时,最小系统能够启动(因为最小启动系统没有原来磁盘中的 sda)。
            首先通过 lsblk -f 查看 sdasdb 两个硬盘分区的 UUID ,将它们复制下来(可以粘贴到其他文件中或者干脆开启两个终端);
            notion image
            然后进入 grub2 目录,cd /mnt/boot/grub2 ,通过 ll | grep grub 指令可以查询到 grub.cfg 文件:
            notion image
            vim grub.cfg 指令打开 grub.cfg 文件,输入 /10_linux 定位到需要修改的段落,认真观察下图所示部分与 lsblk -f 指令输出的 UUID 的异同。
            背景换成了白色,看的更清楚。图中的 UUID 与你们的应该是不同的,每个 Linux 系统下的 UUID 都不一样。
            背景换成了白色,看的更清楚。图中的 UUID 与你们的应该是不同的,每个 Linux 系统下的 UUID 都不一样。
            我们需要将原先为 sda /boot 分区的 UUID 替换为 sdb /mnt/boot 分区的 UUID(图中绿框部分需要作出的修改),将 sda / 根分区的 UUID 替换为 sdb /mnt/sysroot 分区的 UUID (图中蓝框部分需要作出的修改)。
            在上图的黄框部分,第一个黄框部分添加语句为 selinux=0 init=/bin/bash (记得在输入语句前先加上一个空格);
            第二个黄框部分添加的语句为 selinux=0 init=/bin/bash ,与第一个黄框部分一样。
            修改后的文件如下图所示:
            notion image
             
            创建目标根文件系统 & 迁移所需指令和库文件
            创建目标根文件系统:
            mkdir -pv /mnt/sysroot/{etc/rc.d,usr,var,proc,sys,dev,lib,lib64,bin,sbin,boot,srv,mnt,media,home,root}
            这些核心的目录即便后续不使用也是需要创建的。
            迁移库文件:
            cp /lib64/. /mnt/sysroot/lib64/cp /bin/bash /mnt/sysroot/bin/
            这两条指令必须要执行,否则连最基本的指令也无法使用;
            迁移自定义指令:
            由过去所学 Linux 目录结构可知,Linux 的很多指令都存放在 /bin 目录和 /sbin 目录下,因此我们可以将需要用到的指令通过 cp /bin/指令名称 /mnt/sysroot/bin 进行移植。
            📌
            注意,在进行这一步操作时,需要确保 sdb 硬盘已经挂在到 /mnt/sysroot/bin 目录下了,前面所进行的挂载操作都是临时性的,并没有设置自动挂载(未自动挂载会导致重启后先前的挂载指令失效)。
            可以尝试移植两个指令: ① cp /bin/ls /mnt/sysroot/bin ; ② cp /sbin/reboot /mnt/sysroot/bin
            创建 min_Linux 系统
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            notion image
            最后回到配置页面再点击确定即可。
            配置完成后,启动 min_Linux 系统,出现以下页面就代表创建成功了!!
            notion image
            📌
            如果是按照以上内容完整配置一遍下来,应该一次就能够成功了,弹幕中有很多人配置了多次都没有成功,可能是太心急了,漏掉了一些步骤。只要细心配置,走一步看一步,一次就能够成功了。
            min_Linux 系统的测试
            假设在 CentOS 中移植了下面这两条指令:
            cp /bin/ls /mnt/sysroot/bin ; ② cp /sbin/reboot /mnt/sysroot/bin
            min_Linux 系统打开后,由于没有配置环境,因此需要使用 /bin/指令名称 的形式进行调用。
            在调用第一条指令的时候, /bin/ls 成功实现了显示当前列表,不过在使用第二条指令的时候,却提示了报错,可能这条指令还需要关联其他指令才能使用。
            notion image

            📌
            最后一部分可视化的课程并没有做相关的笔记,未来如果有用到再进行学习。
             
             
             
             
             
             
             
            如果本篇笔记对你有用,能否『请我吃根棒棒糖🍭 』🤠…
            Loading...