linux学习笔记

这个笔记比较全面的记录了本人学习Linux的过程,内容还是比较系统、全面的。学习参考的文档以及教程来源繁多,但都吸取了其中比较好的精华,并在此基础上有所拓展深入。本次笔记更多还是在于Linux命令使用上的总结,对于日后的运维学习必定有所帮助…

一、概念

Linux 是一套免费使用和自由传播的类 Unix 操作系统,是一个基于 POSIX 和 UNIX 的多用户、多任务、支持多线程和多 CPU 的操作系统。

目前市面上较知名的发行版有:Ubuntu、RedHat、CentOS、Debian、Fedora、SuSE、OpenSUSE、Arch Linux、SolusOS 等。但大体上分类为RedHat系列和Debian系列。所以本文档主要是使用CentOS并辅助性地掺杂Ubuntu一起进行讲述的。

1. 终端命令格式

Linux 刚面世时并没有图形界面,所有的操作全靠命令完成。对于命令的使用需要注意其格式。

1
command [-options] [parameter]

说明:

  • command:命令名,相应功能的英文单词或单词的缩写

  • [-options]:选项,可用来对命令进行控制,也可以省略

  • parameter:传给命令的参数,可以是 零个一个 或者 多个

  • [] 代表可选

2. 查阅命令的帮助文档信息

可通过在命令后加--help选项或者在命令的前面添加man命令来查看相关命令的帮助文档信息。

2.1 --help

1
2
3
4
#显示command命令的帮助信息
command --help
#--help可简写为-h
command -h

2.2 man

1
2
#查阅command命令的使用手册
man command

manmanual 的缩写,是 Linux 提供的一个 手册,包含了绝大部分的命令、函数的详细使用说明

使用 man 时的操作键:

操作键功能
空格键显示手册页的下一屏
Enter 键一次滚动手册页的一行
b回滚一屏
f前滚一屏
q退出
/word搜索 word 字符串

💡 提示:

初级阶段只需要 知道 通过以下两种方式可以查询命令的帮助信息

先学习常用命令常用选项的使用即可,工作中如果遇到问题可以借助 网络搜索

二、基础命令

由于Linux命令实在太多,下面先介绍最最常用的通用基本操作命令。后面章节会扩展性地讲述其他命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#查看当前文件夹下的内容,list
ls

#查看当前所在文件夹,print wrok directory
pwd

#切换文件夹,change directory
cd [目录名]

#如果文件不存在,新建文件,touch
touch [文件名]

#创建目录,make directory
mkdir [目录名]

#删除指定的文件名,remove
rm [文件名]

#清屏,clear
clear

三、命令操作技巧

在使用终端命令的过程中,使用一些操作技巧可以辅助我们更有效率地完成工作。

1. 放大终端窗口的字体显示

ctrl + shift + =

2. 缩小终端窗口的字体显示

ctrl + -

3. 自动补全

在敲出 文件目录命令 的前几个字母之后,按下 tab 键。如果输入的没有歧义,系统会自动补全,如果还存在其他 文件目录命令,再按一下 tab键,系统会提示可能存在的命令。

4. 终端历史命令切换

光标键可以在曾经使用过的命令之间来回切换

5. 退出执行中的命令

如果想要退出选择,并且不想执行当前选中的命令,可以按 ctrl + c

四、文件管理

1. 文件系统

Windows 文件系统

  • Windows 下,打开 “计算机”,我们看到的是一个个的驱动器盘符:

001_Windows下的多个盘

  • 每个驱动器都有自己的根目录结构,这样形成了多个树并列的情形,如图所示:

001-Windows下多个盘为节点的目录分支

Linux 文件系统

Linux目录结构
  • Linux 下,我们是看不到这些驱动器盘符,我们看到的是文件夹(目录):

002_Ubuntu文件目录

  • Ubuntu 没有盘符这个概念,只有一个根目录 /,所有子目录和文件都在它下面

003-Linux的树形示意图

Linux主要目录介绍
  • /:根目录,在 linux 下有且只有一个根目录,所有的东西都是从这里开始,当在终端里输入 /home,其实是在告诉电脑,先从 /(根目录)开始,再进入到 home 目录。

  • /bin/usr/bin:可执行二进制文件的目录,如常用的命令lstarmvcat等。

  • /boot:放置 linux 系统启动时用到的一些文件,如 linux 的内核文件:/boot/vmlinuz,系统引导管理器:/boot/grub

  • /dev:存放linux系统下的设备文件,访问该目录下某个文件,相当于访问某个设备,常用的是挂载光驱。

  • /etc:系统配置文件存放的目录,不建议在此目录下存放可执行文件,重要的配置文件有:

    /etc/inittab

    /etc/fstab

    /etc/init.d

    /etc/X11

    /etc/sysconfig

    /etc/xinetd.d

  • /home:存放系统中用户的主目录。

    新增用户账号时,用户的主目录默认为/home目录下的一个用户同名的子目录中。如Linux系统存在用户test,则test用户的主目录为: /home/test

    ~ 符号表示当前用户的主目录路径。

  • /lib/usr/lib/usr/local/lib:系统使用的函数库的目录,程序在执行过程中,需要调用一些额外的参数时需要函数库的协助。

  • /lost+fount:系统异常产生错误时,会将一些遗失的片段放置于此目录下。

  • /mnt/media:光盘默认挂载点,通常光盘挂载于 /mnt/cdrom下,但也不一定,可以选择任意位置进行挂载。

  • /opt:给主机额外安装软件所摆放的目录

  • /proc:此目录的数据都在内存中,如系统核心,外部设备,网络状态,由于数据都存放于内存中,所以不占用磁盘空间,比较重要的文件有:

    /proc/cpuinfo

    /proc/interrupts

    /proc/dma

    /proc/ioports

    /proc/net/

  • /root:系统管理员root的主要目录。

  • /sbin/usr/sbin/usr/local/sbin:放置系统管理员使用的可执行命令,如 fdiskshutdownmount等。与/bin 不同的是,这几个目录是给系统管理员 root 使用的命令,一般用户只能"查看"而不能设置和使用。

  • /tmp:一般用户或正在执行的程序临时存放文件的目录,任何人都可以访问,重要数据不可放置在此目录下。

  • /srv:服务启动之后需要访问的数据目录,如 www 服务需要访问的网页数据存放在 /srv/www 内。

  • /usr:应用程序存放目录:

    /usr/bin:存放应用程序

    /usr/share:存放共享数据

    /usr/lib:存放不能直接运行的,却是许多程序运行所必需的一些函数库文件

    /usr/local:存放软件升级包

    /usr/share/doc:系统说明文件存放目录

    /usr/share/man:程序说明文件存放目录

  • /var:放置系统执行过程中经常变化的文件:

    /var/log:随时更改的日志文件

    /var/spool/mail:邮件存放的目录

    /var/run:程序或服务启动后,其 PID 存放在该目录下

2. 常用命令

1)列出目录文件(ls、tree)

1
2
3
4
5
6
#列出目录文件
ls

#树状形式列出目录文件
#选择-d:只显示目录
tree

ls 是英文单词 list 的简写,其功能为列出目录的内容,是用户最常用的命令之一,类似于 DOS下的 dir 命令

常用选项:

  • -a:显示指定目录下所有子目录与文件,包括隐藏文件
  • -l:以列表方式显示文件的详细信息
  • -h:配合 -l 以人性化的方式显示文件大小

通配符的使用:

  • *:代表任意个数个字符
  • ?:代表任意一个字符,至少 1 个
  • [abc]:匹配 a、b、c 中的任意一个
  • [a-f]:匹配从 a 到 f 范围内的的任意一个字符

Linux 下文件和目录的特点:

  • Linux 文件 或者 目录 名称最长可以有 256 个字符
  • . 开头的文件为隐藏文件,需要用 -a参数才能显示
  • .代表当前目录
  • .. 代表上一级目录

计算机中文件大小的表示方式

单位英文含义
字节B(Byte)在计算机中作为一个数字单元,一般为 8 位二进制数
K(Kibibyte)1 KB = 1024 B,千字节 (1024 = 2 ** 10)
M(Mebibyte)1 MB = 1024 KB,百万字节
千兆G(Gigabyte)1 GB = 1024 MB,十亿字节,千兆字节
T(Terabyte)1 TB = 1024 GB,万亿字节,太字节
P(Petabyte)1 PB = 1024 TB,千万亿字节,拍字节
E(Exabyte)1 EB = 1024 PB,百亿亿字节,艾字节
Z(Zettabyte)1 ZB = 1024 EB,十万亿亿字节,泽字节
Y(Yottabyte)1 YB = 1024 ZB,一亿亿亿字节,尧字节

2)切换目录( cd )

1
2
3
4
5
6
7
8
9
10
#切换到/usr/local/share目录里
cd /usr/local/share
#切换到当前用户的主目录(/home/用户目录)
cd ~ #或:cd
#保持在当前目录不变
cd .
#切换到上级目录
cd ..
#在最近两次工作目录之间来回切换
cd -
  • cd 是英文单词 change directory 的简写,其功能为更改当前的工作目录,也是用户最常用的命令之一。
  • 注意:Linux 所有的 目录文件名 都是大小写敏感的。
  • 关于相对路径和绝对路径的说明:
  • 相对路径 在输入路径时,最前面不是 / 或者**~**,表示相对 当前目录 所在的目录位置
  • 绝对路径 在输入路径时,最前面是 /或者~,表示从 根目录/家目录 开始的具体目录位置

3)创建和删除操作(touch、mkdir、rm)

1
2
3
4
5
6
7
8
9
10
11
#创建文件
touch filename.txt

#创建目录
mkdir test-dir

#删除文件或目录
#-f:强制删除,忽略不存在的文件,无需提示
#-r:递归地删除目录下的内容,删除文件夹时必须加此选项
rm -f filename.txt #强制删除filename.txt文件
rm -rf test-dir #强制删除目录以及其内容

4)拷贝和移动文件(cp、mv)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
##复制文件或者目录
#-i:覆盖文件前提示
#-r:若给出的源文件是目录文件,则 cp 将递归复制该目录下的所有子目录和文件,目标文件必须为一个目录名
cp 源文件 目标文件

##移动文件或者目录 或 重命名
# mv命令(mv英文:move)可以用来移动文件或目录,也可以给文件或目录重命名
#-i:覆盖文件前提示
mv 源文件 目标文件

#示例 1:将一个目录移动为另一个目录
#如果目标目录已经存在,则将原目录移动到已存在的目标目录里面
#如果目标目录不存在,则将原目录移动为一个新的目标目录(即目录重命名)
mv source_dir dest_dir #移动过程包括所有文件(含隐藏文件)
#示例 2:将一个目录中的所有文件(包括隐藏文件)移动到另一个目录
mv source_dir/* dest_dir/ #移动过程包括仅包括所有非隐藏文件
mv source_dir/.* dest_dir/ #移动过程包括仅包括所有隐藏文件

5)查看文件内容(cat、more 、grep、tail)

(1)cat 查看文件的所有内容

cat (concatenate)命令可以用来 查看文件内容创建文件文件合并追加文件内容 等功能。

cat 会一次显示所有的内容,适合 查看内容较少 的文本文件。

1
2
#查看hello.txt文件的所有内容
cat hello.txt

常用选项:

  • -b:覆对非空输出行编号
  • -n:对输出的所有行编号

Linux 中还有一个 nl 的命令和 cat -b 的效果等价

(2)more 分屏显示文件内容

more 命令可以用于分屏显示文件内容,每次只显示一页内容

适合于 查看内容较多的文本文件

1
2
#分屏显示hello.txt文件内容
more hello.txt

使用 more 的操作键:

操作键功能
空格键显示手册页的下一屏
Enter 键一次滚动手册页的一行
b回滚一屏
f前滚一屏
q退出
/word搜索 word 字符串
(3)grep 搜索文本文件内容

Linux 系统中 grep 命令是一种强大的文本搜索工具。

grep允许对文本文件进行 模式查找,所谓模式查找,又被称为正则表达式。

1
2
#显示匹配包含qcmoke字符串的行及行号
grep -n qcmoke hello.txt

命令选项:

  • -n:显示匹配行及行号
  • -v:显示不包含匹配文本的所有行(相当于求反)
  • -i:忽略大小写

常用的两种模式查找:

  • ^a: 行首,搜寻以 a 开头的行
  • ke$:行尾,搜寻以 ke 结束的行
(4)tail 取出文件后面几行
1
2
3
4
5
6
7
8
#取出文件后面10行
tail hello.txt

# 默认的情况中,显示最后的十行!若要显示最后的 20 行,就得要这样:
tail -n 20 /etc/nginx/nginx.conf

#侦测文件尾部10行
tail -n 10 -f ~/logs/web2019-10-10.log

命令选项:

  • -n:后面接数字,代表显示几行的意思
  • -f:侦测文件尾部,要等到按下[ctrl]-c才会结束tail的侦测即,如果文件尾部内容被更改,也会随着显示最新尾部内容,常用于查看日志。

6)查找文件( find )

find 命令功能非常强大,通常用来在 特定的目录下 搜索 符合条件的文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#搜索主目录下,文件名包含hello的文件
find ~ -name "hello*"

#搜索/etc目录下,所有以.conf为扩展名的文件
find /etc -name "*.conf"

#搜索/home目录下,以数字1开头的文件
find /home ~ -name "1*"

#-type f: 只查找普通文件;-not -name 排除文件名包含 “test” 字符串的文件
find /path/to/dir -type f -name "*.txt" -not -name "*test*"

#使用 -not -path 参数排除不符合条件的目录
find . -name "node_modules" -not -path "./test/*"


#查找出当前目录及所有子目录下的文件大小大于1G且小于3G的所有文件,并显示出其文件大小
# -type d 表示查找的对象是目录
# -exec du -h {} \; 表示对找到的每个目录执行 du -h 命令,{} 会被替换为找到的目录路径。
find . -type f -size +1G -size -3G -exec du -h {} \;

说明:

  • -name pattern: #按照文件名匹配模式查找文件。例如 -name “*.txt” 查找扩展名为 .txt 的文件。
  • -iname pattern: #类似 -name,但是不区分大小写。
  • -type type: #根据文件类型查找文件,type 可以为 f (普通文件)、d (目录)、l (符号链接) 等。
  • -mtime n: #查找在 n 天前被修改过的文件,n 为负数表示查找 n 天内被修改过的文件。
  • -size n[bck]: #查找文件大小为 n 的文件,单位为字节(默认)、块或千字节。b 表示块,c 表示千字节。
  • -user name: #查找属于指定用户名的文件。
  • -group name: #查找属于指定用户组的文件。
  • -perm mode: #查找权限与指定参数 mode 匹配的文件。mode 可以为类似 644 这样的八进制数,也可以为类似 u=rw,g=r,o=r 这样的符号表示法。
  • -exec command {} \;: #对每个找到的文件执行 command 命令。其中 {} 表示当前匹配到的文件名,; 表示命令结束。
  • -not expr: #对表达式 expr 求反,即排除满足条件的文件。
  • -path pattern: #查找路径名匹配模式的文件。例如 -path “/home/user/*.txt” 查找 /home/user/ 目录下所有扩展名为 .txt 的文件。
  • 如果省略路径,表示在当前文件夹下查找

7)查看目录或文件占用大小( du )

1
2
3
4
5
6
7
8
9
10
#递归查看目录及其子目录的大小(不含非目录的文件大小)
du -h [目录名]
#查看指定目录的总大小(不含子目录和文件大小)
du -sh [目录名]
#查看目录、子目录、文件的大小
du -ah [目录名]
#查看目录下所有一级子目录、文件的大小
du -ah --max-depth=1 [目录名]
#查看目录下所有一级子目录、文件的大小,并进行倒序排序
du -ah --max-depth=1|sort -nr [目录名]

说明:

  • -s:只显目录的总大小,不显示每个子目录和文件的大小。
  • -a:列出所有文件和子目录的大小,而不仅仅是目录。
  • -h:以人类可读的方式显示文件大小,例如:1K、4.5M、2G 等。
  • -b:以字节为单位显示文件大小。
  • -c:同时显示多个文件或目录的总大小。
  • -x:不递归处理指定目录下的子目录。

8)链接( ln )

简要概述

001_文件软硬链接示意图

软链接
1
2
3
#创建文件的软链接,用通俗的方式讲类似于Windows下的快捷方式。
#删除软链接不会影响源文件,但源文件被删除了,那么软连接就不可用了
ln -s <被链接的源文件绝对路径> <链接文件路径>
  • 软链接的特点:

(1)软链接,以路径的形式存在。类似于Windows操作系统中的快捷方式

(2)软链接可以 跨文件系统 ,硬链接不可以

(3)软链接可以对一个不存在的文件名进行链接

(4)软链接可以对目录进行链接

  • 注意:

(1)没有 -s 选项建立的是一个 硬链接文件(对于硬链接文件,两个文件占用相同大小的硬盘空间,工作中几乎不会建立文件的硬链接)

(2)被链接的源文件要使用绝对路径,不能使用相对路径,这样可以方便移动链接文件后,仍然能够正常使用

硬链接
1
2
#删除硬链接,不会影响源文件,同样的删除源文件也不会影响硬链接,只删除一个连接并不影响索引节点本身和其它的连接,只有当最后一个连接被删除后,文件的数据块及目录的连接才会被释放
ln 被链接的源文件 链接文件
  • 硬链接的特点:

(1)硬链接,以文件副本的形式存在。但不占用实际空间。

(2)不允许给目录创建硬链接

(3)硬链接只有在同一个文件系统中才能创建

  • 说明:

在 Linux 中,文件名文件的数据 是分开存储的

在 Linux 中,只有文件的 硬链接数 == 0 才会被删除

使用 ls -l 可以查看一个文件的硬链接的数量

在日常工作中,几乎不会建立文件的硬链接,知道即可

9)打包 和 解包( tar )

tar 是 Linux 中最常用的 备份工具,此命令可以 把一系列文件 打包到 一个大文件中,也可以把一个 打包的大文件恢复成一系列文件

1
2
3
4
5
# 打包文件(不压缩)
tar -cvf 打包文件.tar 被打包的文件/路径...

# 解包文件
tar -xvf 打包文件.tar

选项说明

  • c:生成档案文件,创建打包文件
  • x:解开档案文件
  • v:列出归档解档的详细过程,显示进度
  • f:指定档案文件名称,f 后面一定是 .tar 文件,所以必须放选项最后

注意:f 选项必须放在最后,其他选项顺序可以随意

10)压缩 和 解压缩

(1)gzip

gzip 是linux中常见的压缩/解压工具,最常见的使用对象是*.gz格式的文件。

OPTIONS
-c --stdout --to-stdout 结果写到标准输出,原文件保持不变
-d --decompress --uncompress 解压
-k --keep 压缩或者解压过程中,保留原文件
-r --recursive
-t --test 检查压缩文件的完整性
-v --verbose 显示每个文件的名子和压缩率
-<压缩效率>  压缩效率是一个介于1-9的数值,预设值为"6",指定愈大的数值,压缩效率就会愈高。

  • –best  此参数的效果和指定"-9"参数相同。
  • –fast  此参数的效果和指定"-1"参数相同。

示例1,压缩文件
原文件名为file1.txt,压缩后原文件消失,压缩后文件名为file1.txt.gz

1
2
3
4
5
root@ubuntu:/tmp# ls -l file1.*
-rw-r--r-- 1 root root 12383865 Aug 21 08:08 file1.txt
root@ubuntu:/tmp# gzip file1.txt
root@ubuntu:/tmp# ls -l file1.*
-rw-r--r-- 1 root root 134416 Aug 21 08:08 file1.txt.gz

示例2,解压文件

1
2
3
root@ubuntu:/tmp# gzip -d file1.txt.gz
root@ubuntu:/tmp# ls -lh file1.*
-rw-r--r-- 1 root root 12M Aug 21 08:08 file1.txt

示例3,压缩的时候,显示压缩率

1
2
root@ubuntu:/tmp# gzip -v file1.txt
file1.txt: 98.9% -- replaced with file1.txt.gz

示例4,一条命令压缩多个文件,压缩之后,是各自分开的:

1
2
3
4
5
root@ubuntu:/tmp# gzip file1.txt file2.txt
root@ubuntu:/tmp# ls -l
total 1348
-rw-r--r-- 1 root root 134416 Aug 21 08:08 file1.txt.gz
-rw-r--r-- 1 root root 392 Aug 21 08:15 file2.txt.gz

示例5,压缩过程中,保留原文件

1
2
3
root@ubuntu:/tmp# gzip -k file1.txt
root@ubuntu:/tmp# ls file1.*
file1.txt file1.txt.gz

示例6,压缩到标准输出中
可以连接两个文件

1
2
3
root@ubuntu:/tmp# cat file1.txt file2.txt | gzip > foo.gz
或者
root@ubuntu:/tmp# gzip -c file1.txt file2.txt > foo.gz
(2)gunzip

解压gz格式文件(不保留压缩文件)

1
2
3
4
5
[root@localhost test]# ls
test1.txt.gz test2.txt.gz
[root@localhost test]# gunzip test1.txt.gz test2.txt.gz
[root@localhost test]# ls
test1.txt test2.txt
(3)tar 和 gzip

命令结合可以使用实现文件打包和压缩

  • tar 只负责打包文件,但不压缩
  • gzip 压缩 tar 包后,其扩展名一般用 xxx.tar.gz

Linux 中,最常见的压缩文件格式就是 xxx.tar.gz

  • tar 命令中有一个选项 -z 可以调用 gzip,从而可以方便的实现压缩和解压缩的功能
  • 命令格式如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#压缩文件
gzip test1.txt test2.txt #会生成 test1.txt.gz test2.txt.gz

#压缩tar包
gzip 打包文件名.tar #从tar包变成tar.gz压缩包,这个过程不会保留原来放入tar包

# 打包并压缩文件
tar -zcvf 打包文件名.tar.gz 被压缩的文件/路径... #自动先完成将各个文件打包生成xxx.tar,后压缩生成xxx.tar.gz

# 解压缩并解包
tar -zxvf 打包文件名.tar.gz #自动先完成将xxx.tar.gz解压缩生成xxx.tar,后完成解包生成各个文件

# 解压缩并解包,解压时去除一个顶级目录层次
tar -zxvf 打包文件名.tar.gz --strip-components=1

# 解压缩并解包到指定路径
tar -zxvf 打包文件名.tar.gz -C 目标路径

常用选项:

  • -C:解压缩到指定目录,注意:要解压缩的目录必须存在
  • --strip-components=1:解压时去除一个顶级目录层次
(4)bzip2
  • tarbzip2 命令结合可以使用实现文件 打包和压缩(用法和 gzip 类似)
    • tar 只负责打包文件,但不压缩,
    • bzip2 压缩 tar 打包后的文件,其扩展名一般用 xxx.tar.bz2
  • tar 命令中有一个选项 -j 可以调用 bzip2,从而可以方便的实现压缩和解压缩的功能
  • 命令格式如下:
1
2
3
4
5
# 压缩文件
tar -jcvf 打包文件.tar.bz2 被压缩的文件/路径...

# 解压缩文件
tar -jxvf 打包文件.tar.bz2
(5)zip 和 unzip

zip 是一个常用的命令行工具,用于在 Linux 和类Unix系统上创建和管理ZIP压缩文件。

命令常用选项

  • -r:递归压缩,即压缩目录
  • -j:仅存储文件,不包含目录路径。在压缩包中只保留文件名。
  • -u:仅更新压缩包中的新文件和修改过的文件。
  • -d:从压缩包中删除指定的文件或目录。
  • -l:显示压缩包中的文件列表,不解压缩。
  • -q:安静模式,不显示任何输出。
  • -v:显示详细的压缩过程信息。
  • -C <目录>:在创建压缩包之前切换到指定目录。
  • -x <模式>:排除匹配模式的文件或目录。
  • -z:压缩时显示进度百分比。
  • -e:加密压缩包。
  • -P <密码>:设置压缩包的密码。
  • -T:测试压缩包的完整性。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#压缩文件
zip test.zip test1.txt test2.txt

#递归压缩目录
zip -r test.zip /opt/test/
#注意压缩目录,压缩包里的目录结构会默认保留目标目录的完整路径,如果希望使用想对路径,那么应该cd到目标目录后再通过相对路径来压缩
cd /opt && zip -r test.zip test/

#加密压缩
zip -r -e -P 123456 my_archive.zip my_directory

#实战示例
cd /opt
rm -f backup-*
zip -r -e -P 123456 "backup-$(date +'%Y%m%d%H%M%S').zip" \
./* \
-x "./containerd/*" \
-x "./blog/*" \
-x "./temp/*" \
-x "*/logs/*" \
-x "*/log/*"

unzip 是一个常用的命令行工具,用于解压缩 ZIP 压缩包

常用选项:

  • -d <目标目录>:指定解压缩的目标目录,将压缩包中的文件提取到指定目录。
  • -l:显示压缩包中的文件列表,不解压缩。
  • -o:覆盖目标目录中已存在的文件,而不进行确认提示。
  • -q:安静模式,减少输出信息。
  • -v:显示详细的解压缩过程信息。
  • -x <模式>:排除匹配模式的文件,不进行解压缩。
  • -P <密码>:指定密码来解压缩。
  • -j:解压缩时跳过目录路径,将文件直接提取到当前目录。
1
2
3
4
5
6
7
#默认解压到当前目录
unzip test.zip
#解压到指定目录
unzip test.zip -d path

#解密并解压缩
unzip -P 123456 my_archive.zip

11)重定向( >>>

Linux 允许将命令执行结果重定向到一个文件,将本应显示在终端上的内容输出或者追加到指定文件中。

1
2
3
4
#覆盖输出内容到文件中
echo "hello" > test.txt
#追加内容到文件中
echo "hello" >> test.txt
  • > 表示输出,会覆盖文件原有的内容
  • >> 表示追加,会将内容追加到已有文件的末尾

12)管道( |

Linux 允许将 一个命令的输出可以通过管道做为另一个命令的输入。使用操作如下:

1
2
ps -ef | grep nginx
more test.txt | grep hello

可以理解现实生活中的管子,管子的一头塞东西进去,另一头取出来,这里 | 的左右分为两端,左端塞东西(写),右端取东西(读)

13)统计( wc

wc(Word Count)命令用于统计文件的行数、单词数和字节数等信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
wc [选项] 文件列表


##示例1:
wc example.txt
#输出如下:
# 2 5 28 example.txt
#分别表示 2 行、5 个单词、28 个字节。
#如果执行 wc -l example.txt,则只输出行数,如下:
# 2 example.txt

##示例2:
#统计某个目录下的所有以 .mp4 结尾的文件数量
ls -l /path/to/dir | grep '\.mp4$' | wc -l
#递归地统计某个目录下的所有以 .mp4 结尾的文件数量
find /path/to/dir -type f -name "*.mp4" | wc -l

常用选项:

  • -l:只显示行数。
  • -w:只显示单词数。
  • -c:只显示字节数。

3. 文件权限管理

在 Linux 系统中,不同的用户对于不同的系统资源拥有不同的使用权限。在 Linux 中,可以指定每一个用户针对不同的文件或者目录的不同权限。文件(目录)的权限包括如下:

序号权限英文缩写数字代号
01readr4
02writew2
03执行excutex1

1. 文件的详细信息

1
2
#查看文件夹下文件的详细信息(目录也是一种文件)
ls -l

打印结果从左到右依次是:

  • 权限,第 1 个字符如果是 d 表示目录

  • 硬链接数,通俗地讲,就是有多少种方式,可以访问到当前目录/文件

  • 拥有者,家目录下 文件/目录 的拥有者通常都是当前用户

  • ,在 Linux 中,很多时候,会出现组名和用户名相同的情况,后续会讲

  • 大小

  • 最后修改时间

  • 名称

15418513400061541851399509

002_权限示意图

2. 设置文件权限

1
2
3
4
5
6
7
8
# 设置文件或目录的所属用户和用户组
chown user:group file

# 递归修改文件|目录所属的用户组
chgrp -R group file

# 递归修改文件或目录的操作权限
chmod -R 755 file

chmod 在设置操作权限时,可以简单地使用三个数字分别对应:所属用户、所属用户组、 和其他用户的权限

1
2
# 直接修改文件|目录的 读|写|执行 权限,但是不能精确到 拥有者|组|其他
chmod +/-rwx file

004_文件权限示意图

常见数字组合有(u表示用户/g表示组/o表示其他):

777 ===> u=rwx,g=rwx,o=rwx

755 ===> u=rwx,g=rx,o=rx

644 ===> u=rw,g=r,o=r

3. 文件属性模式

lsattr

lsattr 命令用于显示文件的属性,使用方式如下

1
2
3
4
# 查看file.sh 文件的属性
lsattr file.sh
# 查看当前目录下所有文件以及文件夹的属性
lsattr

详细说明请参考:

📚https://www.runoob.com/linux/linux-comm-lsattr.html

chattr

chattr 用于修改文件属性。

1
chattr [-RV][-v<版本编号>][+/-/=<属性>][文件或目录...]

选项:

  • -R 递归处理,将指定目录下的所有文件及子目录一并处理。
  • -v <版本编号> 设置文件或目录版本。
  • -V 显示指令执行过程。
  • +<属性> 开启文件或目录的该项属性。
  • -<属性> 关闭文件或目录的该项属性。
  • =<属性> 指定文件或目录的该项属性。

这项指令可改变存放在ext2文件系统上的文件或目录属性,这些属性共有以下几种模式:

  • a:让文件或目录仅供附加用途。
  • b:不更新文件或目录的最后存取时间。
  • c:将文件或目录压缩后存放。
  • d:将文件或目录排除在倾倒操作之外。
  • i:不得任意更动文件或目录。
  • s:保密性删除文件或目录。
  • S:即时更新文件或目录。
  • u:预防意外删除。

该命令请切换至 root 用户下使用。

1
2
3
4
5
6
7
8
# 为 file.sh 文件增加 i 标识
chattr +i file.sh
# 为 file.sh 文件去除 i 标识
chattr -i file.sh
# 为 file.sh 增加 i, a 两个标识
chattr +ia file.sh
# 为 file.sh 文件移除 i, a 两个标识
chattr -ia file.sh

详细说明请参考:

📚https://baike.baidu.com/item/chattr/9841067?fr=aladdin

📚https://www.runoob.com/linux/linux-comm-chattr.html

文件属性模式相关问题

Linux 文件/文件夹无法删除问题解决方案

服务器黑客攻击后,如果他们对某些文件(例如病毒文件)的属性模式进行修改,导致我们无法轻易删除这些文件,同时采用 root 用户也可能无法使用rm命令删除,那么这就会带来巨大的隐患问题。

案例:

假设黑客使用如下命令对文件的属性模式进行了修改。

1
chattr +ia file.sh

那么使用如下rm命令是没有权限删除的。即使是 root 用户也无法删除。

1
rm -rf file.sh

这种情况就涉及到chattr命令相关的文件属性模式了。

由上文中得知当文件设置 i 和 a 任意一个属性我们就无法对文件进行删除操作,那么只要我们移除掉 i, a 属性,然后执行rm命令删除就可以了。

1
2
3
4
5
6
# 移除 i, a 属性
chattr -ia file.sh
# 查看是否移除成功
lsattr file.sh
# 删除文件
rm -rf file.sh

如果文件还未删除成功,则我们需要考虑文件所属的文件夹是否设置了 i 或 a 属性(这一点确实很难发现)

1
2
3
4
5
# 退回上一级
cd ..
# 直接使用 lsattr 命令,这样可以列出当前文件夹下所有文件和文件夹的属性
# 不要使用 lsattr 文件夹 这样的语法,这样是列出该文件夹下的文件的属性
lsattr

如果文件夹被设置则对文件夹的属性执行移除操作,然后再删除文件夹里面的文件

五、用户管理

1. 基本概念

在 Linux 系统中,不论是本机或是远程登录系统,每个系统都必须拥有至少一个用户。用户是 Linux 系统工作中重要的一环,用户管理包括用户与组管理。为了方便用户管理,Linux有组的概念,组的意义在实际应用中,可以预先针对组设置好权限,然后将不同的用户添加到对应的组中,从而不用依次为每一个用户设置权限。

001_组示意图

2. 用户组维护

1
2
3
4
5
6
7
8
#添加组
groupadd 组名

#删除组
groupdel 组名

#查看组信息
cat /etc/group

提示:用户组信息保存在 /etc/group 文件中。

在实际应用中,可以预先针对组设置好权限,然后将不同的用户添加到对应的组中,从而不用依次为每一个用户设置权限。

3. 用户维护

1)创建用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#创建用户
useradd 用户名


#显式创建用户时自动创建用户同名的用户组并添加用户到该组中
useradd -U 用户名

#创建用户时不自动创建用户同名的用户组,则系统会默认添加用户到系统默认的组中
useradd -N 用户名
#系统默认的组配置在/etc/default/useradd里,可通过如下命令查看:
cat /etc/group | grep ":$(grep .*GROUP /etc/default/useradd | sed 's/.*GROUP=//'):"

#创建用户时指定用户组
#-g: 指定将用户添加到的组(默认为用户同名的用户组)
#-G: 指定将用户添加到的多个组
useradd -g 组 用户名
useradd -G 组1,组2 用户名

#创建用户时自动创建用户主目录
useradd -m 用户名
#创建用户时不自动创建用户主目录
useradd -M 用户名


#创建用户时配置登录的Shell路径
useradd -s /bin/bash 用户名

#创建用户时进行密码设置
useradd -p 密码

#创建用户时指定用户的主目录,可以使用-d或--home参数,后面跟上想设定的主目录路径,如下:
useradd -m -d /你的路径/用户名 用户名

#创建用户和同名用户组,不自动创建用户主目录,禁止该用户登录系统
useradd -U -M -s /usr/sbin/nologin 用户名

关于useradd命令说明:

  • 自动创建用户同名的用户组:在Redhat类系统和Debain类系统中,都默认会自动创建用户同名的用户组并添加用户到该组中(如果不需要自动创建则需加选项:-N,则系统会默认添加用户到系统默认的组中)。
  • 自动创建用户主目录:在Redhat类系统中,默认会自动创建用户主目录(如果不需要创建则加选项:-M),而Debain类系统中不会自动创建(如果需要自动创建则需加选项:-m)。
  • 自动配置登录的 Shell 路径:在Redhat类系统和Debain类系统中,都默认会自动配置登录的 Shell 路径(默认为:/bin/bash,自定义登录的 Shell 路径可加选项及参数:-s <path>
  • 密码设置:在Redhat类系统和Debain类系统中,都默认不会进行密码设置(如果需要设置可加选项及参数:-p <password>)。

关于adduser命令的说明:

  • Redhat类系统中,adduseruseradd两个命令是相同的。
  • Debain类系统中,adduseruseradd有所不同,adduser是基于useradd的上层命令,主要表现在adduser默认会自动创建用户主目录,默认会提示密码设置。

2)设置用户密码

1
2
#设置用户密码,如果是普通用户,直接用 passwd 可以修改自己的账户密码
passwd 用户名

3)查看系统的用户信息

1
2
3
4
5
#查看系统中的所有用户信息
cat /etc/passwd

#新建用户后,用户信息会保存在 /etc/passwd 文件中
cat /etc/passwd | grep 用户名

提示:/etc/passwd 是用于保存用户信息的文件;而/usr/bin/passwd 是用于修改用户密码的程序。

/etc/passwd 文件存放的是用户的信息,由 6 个分号组成的 7 个信息,分别是

用户名

密码(x,表示加密的密码)

UID(用户标识)

GID(组标识)

用户全名或本地帐号

家目录

登录使用的 Shell,就是登录之后,使用的终端命令,ubuntu 默认是 dash

4)删除用户

1
2
3
4
5
#删除用户时(默认不会自动删除用户的主目录,默认会删除用户的同名用户组)
userdel 用户名

#删除用户时自动删除用户的主目录
userdel -r 用户名

5)查看系统用户信息

1
2
3
4
5
6
7
8
#查看用户 UID 和 GID 信息,默认当前用户
id [用户名]

#查看当前所有登录的用户列表
who

#查看当前登录用户的账户名
whoami

6)修改用户组和登录的Shell

usermod命令可以用来设置 用户的主组、附加组和登录的Shell,命令格式如下:

1
2
3
4
5
6
7
8
# 修改用户的主组,通常在新建用户时指定,在/etc/passwd的第4列GID对应的组
usermod -g 组 用户名

# 修改用户的附加组,在/etc/group中最后一列表示该组的用户列表,用于指定用户的附加权限
usermod -G 组 用户名

# 修改用户登录 Shell
usermod -s /bin/bash 用户名

提示:设置了用户的附加组之后,需要重新登录才能生效!

7)切换用户

1
2
3
4
5
6
7
8
## 1、切换用户(su)
#su 是 substitute user 的缩写,表示切换用户,默认为 root
#切换用户后,将启动新的 shell 会话,可通过命令 echo $$ 查看“当前会话 ID”的方式来验证
#可指定 -, -l, --login 表示使用登录方式启动一个新的 shell 会话来来切换用户。
#示例:su - 或 su - test1
#如果不指定,则切换用户后新的 shell 会话仍然属于前一个用户,可通过命令 echo $USER 来查看“当前用户”的方式验证
su [username]
#如:su test1 或 su - test1

su 切换用户示意图如下:

003_su和exit示意图

4. 超级用户权限维护

Linux 系统中的 root 用户是超级用户,通常用于系统的维护和管理,对操作系统的所有资源具有所有访问权限,在大多数版本的 Linux 中,都不推荐直接使用 root 账号登录系统,在 Linux 安装的过程中,系统会自动创建一个用户账号,而这个默认的用户称为 “标准用户”。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
## 1、以超级用户权限执行(sudo)
#sudo 表示以超级用户权限执行,即允许普通用户在不切换到超级用户(root)的情况下以 root 用户权限执行命令
#执行 sudo 命令时,要求当前用户必须为 sudo 用户组
#使用 sudo 命令时,必须先输入 root 用户的密码
#使用 sudo 后有 5 分钟的有效期限,超过期限则必须重新输入密码
sudo <command>
#如:sudo ls /root

## 2、添加某用户到 sudo 用户组
#在 Debian 系列系统中,默认使用名为 sudo 的用户组来管理 sudo 访问权限;在 Red Hat 系列系统中,默认使用名为 wheel 的用户组来管理 sudo 访问权限
#具体管理 sudo 访问权限的用户组名称可在 /etc/sudoers 文件中确定(可通过 visudo 命令直接打开该文件)
#由于 Debian 系列系统和 Red Hat 系列系统管理 sudo 访问权限的用户组名称不同,所以对于不同发行版系统操作类似但不一定相同,具体如下:
#(1)先切换到 root 用户
su
#(2)对于 Debian 系列系统
apt install -y sudo #如果没有 sudo 命令,则需要先安装
usermod -a -G sudo <username> #添加某用户到 sudo 用户组,如:usermod -a -G sudo test1
#(3)对于 Redhat 系列系统
yum install -y sudo #如果没有 sudo 命令,则需要先安装
usermod -a -G wheel <username> #添加某用户到 sudo 用户组,如:usermod -a -G wheel test1

5. 用户登录维护

1)查看当前登录到系统上的用户信息

1
2
#查看当前登录到系统上的用户信息
who

示例:

1
2
3
4
[root@vm35218 ~]# who
root pts/0 2023-06-17 09:45 (183.11.72.163)
root pts/1 2023-06-17 09:45 (183.11.72.163)
qcmoke pts/2 2023-06-17 10:00 (183.11.72.163)

2)查看系统中所有用户的最近登录信息

lastlog命令可用于显示每个用户最后一次登录的日期、时间、终端位置和IP地址等信息。

1
2
3
4
5
6
7
#查看系统中所有用户的最近登录信息
lastlog

#如果执行命令失败,提示:/var/log/lastlog: 没有那个文件或目录。则如下解决:
touch /var/log/lastlog
chgrp utmp /var/log/lastlog
chmod 664 /var/log/lastlog

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[root@vm35218 ~]# lastlog
用户名 端口 来自 最后登陆时间
root pts/1 183.11.72.163 六 6月 17 09:45:58 +0800 2023
bin **从未登录过**
daemon **从未登录过**
adm **从未登录过**
lp **从未登录过**
sync **从未登录过**
shutdown **从未登录过**
halt **从未登录过**
mail **从未登录过**
operator **从未登录过**
games **从未登录过**
ftp **从未登录过**
nobody **从未登录过**
systemd-network **从未登录过**
dbus **从未登录过**
polkitd **从未登录过**
sshd **从未登录过**
postfix **从未登录过**
chrony **从未登录过**
gluster **从未登录过**
git **从未登录过**
qcmoke pts/2 183.11.72.163 六 6月 17 10:00:40 +0800 2023
dockremap **从未登录过**
nginx **从未登录过**

3)查看系统中用户的完整登录历史记录

last命令可用于显示每个用户最后一次登录的日期、时间、终端位置和IP地址等信息。

1
2
3
4
5
#查看系统中所有用户的完整登录历史记录
last

#查看系统中指定用户的完整登录历史记录
last root

示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
[root@vm35218 ~]# last
qcmoke pts/2 183.11.72.163 Sat Jun 17 10:00 still logged in
root pts/1 183.11.72.163 Sat Jun 17 09:45 still logged in
root pts/0 183.11.72.163 Sat Jun 17 09:45 still logged in
root pts/1 183.11.73.129 Thu Jun 15 23:39 - 00:22 (00:43)
root pts/0 183.11.73.129 Thu Jun 15 23:39 - 00:22 (00:43)
root pts/1 183.11.72.5 Mon Jun 12 21:54 - 21:54 (00:00)
root pts/0 183.11.72.5 Mon Jun 12 21:54 - 21:54 (00:00)
root pts/1 183.11.72.5 Mon Jun 12 21:32 - 21:32 (00:00)
root pts/0 183.11.72.5 Mon Jun 12 21:32 - 21:32 (00:00)
root pts/1 183.11.72.5 Mon Jun 12 12:45 - 15:02 (02:16)
root pts/0 183.11.72.5 Mon Jun 12 12:45 - 15:02 (02:16)
root pts/1 183.11.72.5 Mon Jun 12 02:38 - 06:33 (03:54)
root pts/0 183.11.72.5 Mon Jun 12 02:38 - 06:33 (03:54)
root pts/1 183.11.75.79 Sun Jun 11 19:03 - 19:03 (00:00)
root pts/0 183.11.75.79 Sun Jun 11 19:03 - 19:03 (00:00)
root pts/1 183.11.75.79 Sun Jun 11 18:43 - 18:43 (00:00)
root pts/0 183.11.75.79 Sun Jun 11 18:43 - 18:43 (00:00)
qcmoke pts/2 183.11.75.79 Sun Jun 11 03:49 - 03:49 (00:00)
root pts/1 183.11.75.79 Sun Jun 11 02:12 - 04:32 (02:19)
root pts/0 183.11.75.79 Sun Jun 11 02:12 - 04:32 (02:19)
root pts/1 183.11.75.79 Sun Jun 11 00:18 - 02:12 (01:53)
root pts/0 183.11.75.79 Sun Jun 11 00:18 - 02:12 (01:53)
reboot system boot 5.13.5-1.el7.elr Sun Jun 11 00:18 - 10:17 (6+09:59)
root pts/2 183.11.75.79 Sun Jun 11 00:01 - down (00:16)
root pts/0 183.11.75.79 Sun Jun 11 00:01 - down (00:16)
root pts/2 183.11.75.79 Sat Jun 10 19:31 - 00:01 (04:30)
root pts/0 183.11.75.79 Sat Jun 10 19:31 - 00:01 (04:30)
root pts/2 183.11.75.79 Sat Jun 10 16:08 - 19:31 (03:22)
root pts/0 183.11.75.79 Sat Jun 10 16:08 - 19:31 (03:22)
root pts/2 183.11.75.79 Sat Jun 10 15:53 - 16:06 (00:12)
root pts/0 183.11.75.79 Sat Jun 10 15:53 - 16:06 (00:12)
root pts/2 183.11.75.79 Sat Jun 10 14:25 - 15:48 (01:23)
root pts/0 183.11.75.79 Sat Jun 10 14:25 - 15:48 (01:23)
root pts/2 183.11.75.79 Sat Jun 10 11:01 - 12:37 (01:36)
root pts/0 183.11.75.79 Sat Jun 10 11:01 - 12:37 (01:36)

4) 踢出登录用户

1
2
3
4
5
#选择登录终端并强制踢出,例如选择踢出使用终端pts/1登录的用户。
#方法一:
pkill -kill -t pts/1
#方法二:
fuser -k /dev/pts/1

案例

1
2
3
4
5
6
7
#先列举当前登录的系统用户
[root@VM_0_6_centos ~]# who
root pts/0 2020-02-28 10:50 (163.125.117.95)
root pts/1 2020-02-28 10:49 (163.125.117.95)
#选择登录终端并强制踢出,可以给他发送后再踢出
[root@VM_0_6_centos ~]# echo "你被管理员踢出了" > /dev/pts/1 && fuser -k /dev/pts/1
/dev/pts/1: 23381

六、软件管理

1. 软件管理简介

1.1 包全名与包名

  • 包全名:操作的包是没有安装的软件包时,使用包全名。
  • 包名:操作已经安装的软件包时使用的包名。linux安装后包名都存在/var/lib/rpm/中的数据库

1.2 Linux包依赖性

  • 树形依赖:a>b>c
  • 环形依赖:a>b>c>a
  • 模块依赖:模块依赖

软件安装的过程:

  • (1)cp类库到系统目录中
  • (2)cp可执行程序和配置文件到系统目录中
  • (3)根据需要选择性配置和启动服务(程序)

对于windows系统还会多出一个步骤,那就是到把启动配置或者程序依赖的配置放到注册表中。

1.3 常见软件包命名原则

(1)Debian 软件包格式:apache2_2.4.18-2ubuntu3_amd64.deb

  • apache2:软件包名
  • 2.4.18 :软件版本
  • 2:软件发布的次数
  • ubuntu3:适合的系统版本
  • amd64:适合的硬件平台
  • deb:Debian 软件包扩展名

(2)RPM 软件包格式:httpd-2.2.15-15.el6.centos.1.i686.rpm

  • httpd:软件包名
  • 2.2.15:软件版本
  • 15:软件发布的次数
  • el6.centos:适合的系统版本
  • i686:适合的硬件平台
  • .rpm:RPM 软件包扩展名

1.4 linux软件包优先级

Required该级别软件包是保证系统正常运行所必须的,如果缺失,系统将毁坏系统工具,比如bash,mount…
Important若缺少该软件包,系统讲运行困难实现系统底层功能的一些程序,比如aptitude,apt-get
Standardlinux系统的标准件常规安装软件,如telnet.tp
Optional该软件包是否安装不影响linux运行用于用户特定的需求,比如×11,mysql,openofice,自开发软件等
Extra该级别可能与高级软件包存冲突

2. Debain 系列系统的软件管理

1)dpkg 本地包管理器

(1)安装
1
2
#i表示install
dpkg -i 软件包全名
(2)卸载
1
2
#r表示remove
dpkg -r 软件包名 #移除包不移除配置文件
1
2
#-P等价于--purg,表示移除包和配置文件
dpkg -P 软件包名 #移除包和配置文件
(3)查询
1
2
3
4
5
dpkg -l  软件包名 #列出当前系统中已经安装的包,包括软件的版本,可以使用dpkg -l | grep 关键字来查询
dpkg -L 软件包名 #列出已安装的包的内容,或者安装位置
dpkg -c 软件包全名 #列出deb包的内容
dpkg -s 软件包名 #查看系统中软件的详细信息 (包含依赖信息)
dpkg --info 软件包全名 #查看未安装的包的信息(包含依赖信息)

2)apt 在线包管理器

APT(Advanced Package Tool)是基于 dpkg 的在线包管理工具,它提供了高级的软件包管理功能,包括包的安装、升级、删除和依赖解决等。APT 通过与软件包仓库进行交互,从远程仓库获取软件包信息并管理软件包的安装和更新。

APT 提供了一些常用的命令行工具:

  1. apt-get:用于安装、升级、卸载软件包,以及处理依赖关系和软件包的下载等。
  2. apt-cache:用于查询软件包的信息,如版本、依赖关系、提供的文件等。
  3. apt-config:用于管理 APT 的配置文件。
  4. apt-key:用于管理软件包的数字签名和密钥。
  5. apt-file:用于查询软件包中的文件列表。
  6. aptitude:一个功能更强大的终端界面的包管理工具,提供交互式的软件包管理功能。

由于 APT 提供的工具集太多,使用太繁杂,故而新版 Debian 系列系统使用 apt 命令来包含囊括apt-getapt-cache 命令,故而现在推荐使用apt命令来替代apt-get等命令。

(1) apt 软件源
(1.1)修改 Ubuntu 软件源为国内源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
##切换到root用户
sudo -i

##安装相关依赖(如系统未安装)
apt update
apt install -y ca-certificates

##备份
cp /etc/apt/sources.list /etc/apt/sources.list_backup

##替换软件源(支持所有ubuntu18.04或更高的系统版本)
MIRRORS_URL=https://mirrors.aliyun.com #阿里源(推荐)
#MIRRORS_URL=https://mirrors.163.com #网易源
VERSION_CODENAME=$(cat /etc/os-release | grep VERSION_CODENAME | sed 's/.*=//') #系统版本代号

cat > /etc/apt/sources.list << EOF
deb $MIRRORS_URL/ubuntu/ $VERSION_CODENAME main restricted universe multiverse
deb-src $MIRRORS_URL/ubuntu/ $VERSION_CODENAME main restricted universe multiverse
deb $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-security main restricted universe multiverse
deb-src $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-security main restricted universe multiverse
deb $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-updates main restricted universe multiverse
deb-src $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-updates main restricted universe multiverse
# deb $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-proposed main restricted universe multiverse
# deb-src $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-proposed main restricted universe multiverse
deb $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-backports main restricted universe multiverse
deb-src $MIRRORS_URL/ubuntu/ $VERSION_CODENAME-backports main restricted universe multiverse
EOF

##更新软件源
apt update

参考:https://developer.aliyun.com/mirror/ubuntu?spm=a2c6h.13651102.0.0.1ecc1b11jbngYS

通过apt update更新软件源到本地并在本地建立新远程软件库所有软件包对应的索引表(数据库形式),所有存放在/var/lib/apt/lists/*

(1.2)修改 Debian 软件源为国内源
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
##切换到root用户
#如果sudo命令没有,则通过root用户安装sudo,如:apt install sudo
sudo -i

##安装相关依赖(如系统未安装)
apt update
apt install -y ca-certificates

##备份
cp /etc/apt/sources.list /etc/apt/sources.list_backup

##替换软件源(支持所有debian系统版本)
MIRRORS_URL=https://mirrors.aliyun.com #阿里源(推荐)
#MIRRORS_URL=https://mirrors.163.com #网易源
#MIRRORS_URL=http://deb.debian.org #官方源
VERSION_CODENAME=$(cat /etc/os-release | grep VERSION_CODENAME | sed 's/.*=//') #系统版本代号
cat > /etc/apt/sources.list << EOF
deb $MIRRORS_URL/debian/ $VERSION_CODENAME main non-free contrib
deb-src $MIRRORS_URL/debian/ $VERSION_CODENAME main non-free contrib
deb $MIRRORS_URL/debian-security/ $VERSION_CODENAME-security main
deb-src $MIRRORS_URL/debian-security/ $VERSION_CODENAME-security main
deb $MIRRORS_URL/debian/ $VERSION_CODENAME-updates main non-free contrib
deb-src $MIRRORS_URL/debian/ $VERSION_CODENAME-updates main non-free contrib
deb $MIRRORS_URL/debian/ $VERSION_CODENAME-backports main non-free contrib
deb-src $MIRRORS_URL/debian/ $VERSION_CODENAME-backports main non-free contrib
EOF

##更新软件源
apt update

参考:

(2)查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#根据关键字搜索可用软件包(等价:apt-cache search 软件包关键字)
apt search 软件包关键字

#查询某个命令所属的安装包(命令所属的软件包安装或未安装都可以查询)
apt install apt-file
apt-file update
apt-file search 命令路径 #如:apt-file search /sbin/ifconfig(注意:apt-file search 不支持使用通配符查询)

#列出所有可用软件包
apt list
#列出已经安装的所有软件包
apt list --installed
#列出已经安装的指定软件包
apt list --installed <package-name> #或者apt list --installed | grep 关键字
#列出可更新的所有软件包
apt list --upgradable

##查看安装包的信息(包括:名称、版本、安装源、包大小、依赖关系、描述等)
apt show <package-name>
##查看软件包政策(包括版本信息、源信息等)
apt policy <package-name>


#检查当前apt的依赖情况
apt check
#查看系统中软件的依赖(正向依赖)
apt depends <package-name>
#查看系统中软件的依赖(反向依赖)
apt rdepends <package-name>

可使用apt-cache子命令来实现查询功能,推荐使用apt命令来查询,其兼容apt-cache

(3) 安装
1
2
3
4
5
6
7
8
9
10
#安装指定的软件包(选项:-y 自动回答yes)
#该命令安装包前不会自动检测软件源的本地缓存,故安装前最好手动执行apt update命令
apt install <package-name>


#修复系统中存在的依赖关系问题(尝试安装缺失的依赖包、删除不再需要的依赖包、修复已损坏的依赖关系等)
apt -f install

#获得包的源码
apt source <package-name>

apt install工作步骤

  • 扫描本地软件列表

  • 软件包依赖检查

  • 从软件包指定的 apt 源中下载软件包

  • 解压软件包并完成配置

默认情况下,apt install 在成功安装软件包后会自动删除下载的软件包文件。如果需要获取软件包文件可如下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#方式1:下载软件包
#下载路径为:/var/cache/apt/archives/ (不能修改)
#该命令下载软件包会强制包括依赖包
#该命令只下载不安装
#只有在系统未安装有软件包时才能下载,如果已经安装了,则无法下载。如果非要下载则只能改用apt download命令,或者卸载包后再下载。
apt install -d <package-name>
#等同:apt install --download-only <package-name>

#方式2:下载软件包
#下载路径为:当前目录(不能修改)
#该命令下载软件包不会包括依赖包,如需下载依赖包请选用apt install -d <package-name>
#无论系统是否已经安装有软件包都能下载
apt download <package-name>

#示例:
apt install -d nginx
apt download nginx
(4) 更新
1
2
3
4
5
6
7
8
#更新软件源的本地缓存(本地缓存:源的软件列表和包的元数据,元数据:包的信息和包的依赖关系,包的信息:版本号、更新日期、作者、描述等)
apt update
#升级更新指定软件包
apt upgrade <package-name>
#升级更新系统所有软件包(升级已安装的软件包,但不会删除或安装其他依赖包)
apt upgrade
#升级更新系统所有软件包(除了升级已安装的软件包,会删除或安装其他依赖包)
apt dist-upgrade

💁‍♂ 提示:以上更新升级操作只是升级当前系统版本的软件包(包括内核版本,通常升级的默认内核版本一般都较低,如需升级更高版本的内核则需要手动安装)。需要说明的是不会升级系统的版本,如果要升级系统版本则需要使用新版本的系统镜像重装系统。

(5) 卸载
1
2
3
4
5
6
7
8
9
10
11
12
13
#卸载软件包(不含配置文件)
apt remove <package-name>
#卸载软件包(含配置文件),命令等价:apt remove --purge <package-name>
apt purge <package-name>

#卸载指定的软件包,并自动删除其依赖包中不再需要的依赖包
apt remove --auto-remove <package-name>
#卸载系统中所有不再需要的依赖包
apt auto-remove
#清除已下载的软件包文件的缓存
#这些包文件通常被存储在 /var/cache/apt/archives 目录下。执行 apt clean 会删除该目录中的所有 .deb 文件
#在Debian系列系统中,通过apt安装或更新的软件,默认会自动保留.deb包缓存文件在缓存目录中。如果希望自定义是否默认保留包缓存文件可参考:https://blog.csdn.net/FoxBryant/article/details/123226245
apt clean

💁‍♂ 提示:不再需要的依赖包是指不再被其他软件包所依赖的包。

3. Redhat 系列系统的软件管理

1)rpm 本地包管理器

(1)安装
1
2
#-i(install)安装; -v(verbose)显示详细信息; -h(hash)显示进度; -nodeps 不检测依赖性
rpm -ivh <package-name>
(2)升级
1
2
#-U(upgrade)升级(更新的是已安装版本的包)
rpm -Uvh <package-name>
(3)卸载
1
2
#-e(erase)卸载; -nodeps 不检查依赖性
rpm -e <package-name>
(4)查询包是否安装
1
2
3
#-q 查询(query); -a 所有(all)
rpm -q <package-name> #查询已经安装的具体包(不能使用通配符)
rpm -qa #查询所有已经安装的包(可使用通配符筛选查询,如:rpm -qa kernel* 或 rpm -qa kernel kernel-*)
(5) 查询软件包详细信息
1
2
3
4
5
6
#-q 查询(query); -i 查询软件信息(information); -p 查询未安装包信息(package)
rpm -qi <package-name>

#例如:
rpm -qi zip #查看系统中已经安装存在的包信息
rpm -qip zip-3.0-23.fc29.x86_64.rpm #查看未安装包信息
(6)查询软件包安装位置
1
2
3
#-q 查询(query)-l 列表(list); -p 查询未安装包信息,用来查看未安装的软件包打算安装到哪些目录里
rpm -ql <package-name> #查询已安装的软件安装到了哪些目录里
rpm -qlp <package-name> #查询未安装的软件包打算安装到哪些目录里

如果忘记包名,可以通过rpm -qa | grep 包名关键字先查看系统中已经安装的相关软件,然后再执行rpm -ql 包名来查看具体路径

(7)查询系统文件所属的软件包
1
2
3
4
5
6
#-f 查询系统文件属于哪个软件包(file)
rpm -qf 系统文件名

#示例:
rpm -qf /usr/bin/bash
rpm -qf /etc/yum.conf
(8) 查询软件包的依赖性
1
2
3
#-R 查询软件包的依赖性(requires);-p 查询未安装包信息(package)
rpm -qR <package-name> #查询已安装包信息
rpm -qRp <package-name> #查询未安装包信息
(9) 软件包完整性校验
1
2
3
4
5
6
7
8
9
#比较已安装软件包的文件与原始软件包中的文件属性(例如文件大小、权限、MD5 校验和等)差异,如果有任何文件被修改、删除或者权限被更改,命令会显示出这些变化。
#选项:-V 校验指定软件包中的文件(verify)
rpm -V <package-name>

# 示例:修改httpd的配置文件后,查看是否被修改
$ yum install -y httpd
$ echo "" >> /etc/httpd/conf/httpd.conf
$ rpm -V httpd
S.5....T. c /etc/httpd/conf/httpd.conf

验证内容中的8个信息的具体内容如下:

  • S:文件大小是否改变
  • M:文件的类型或文件的权限(rwx)是否被改变
  • 5:文件MD5校验和是否改变(可以看成文件内容是否改变)
  • D:设备的中,从代码是否改变
  • L:文件路径是否改变
  • U:文件的属主(所有者)是否改变
  • G:文件的属组是否改变
  • T:文件的修改时间是否改变

文件类型

  • c:配置文件(config file)
  • d:普通文档(documentation)
  • g:幽灵文件(ghost file),幽灵文件是指在 RPM 数据库中存在记录但在实际文件系统中不存在的文件
  • l:授权文件(license file)
  • r:描述文件(read me)

软件包文件的完整性验证(注意和软件包完整性校验的区别):

1
2
#验证软件包文件的完整性(注意是软件包文件,即:“.rpm文件”,主要检查软件包的签名)
rpm --checksig <package_file.rpm>
(10)从RPM包中提取文件
1
2
#提取软件包中的指定文件到当前目录
rpm2cpio .rpm包文件的文件路径 | cpio -idv .rpm包文件中所需提取的文件的路径(可解压查看)

rpm2cpio 是将rpm包转换为cpio格式的命令,cpio 是一个标准工具,它用于创建软件档案文件和从档案文件中提取文件

从RPM包中提取文件可以用来解决误删除系统文件后的补救方法,如下示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#查看ls命令文件所属的软件包(如:coreutils-8.22-24.el7_9.2.x86_64)
rpm -qf /bin/ls

#将ls命令到临时目录里,造成误删假象
mv /bin/ls /tmp/

#下载指定版本的软件包到当前目录
yumdownloader coreutils-8.22-24.el7_9.2.x86_64
# 可通过 yumdownloader -q --urls coreutils-8.22-24.el7_9.2.x86_64 获得软件包URL地址。

#提取ls命令文件到当前目录下(-idv 后接的路径必须与rpm包中的路径相对应)
rpm2cpio ./coreutils-8.22-24.el7_9.2.x86_64.rpm | cpio -idv ./usr/bin/ls

#把ls命令复制/bin/目录,恢复丢失的文件
cp ./usr/bin/ls /bin/

2)yum 线包管理器

yum 是基于 rpm 的在线包管理工具,它提供了高级的软件包管理功能,包括包的安装、升级、删除和依赖解决等。yum 通过与软件包仓库进行交互,从远程仓库获取软件包信息并管理软件包的安装和更新。

(1)yum软件源

centos 默认软件源改为阿里源(以 centos7 为例)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#先确保安装wget用于下载yum源文件
yum install -y wget
#备份旧的配置文件
mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.bak
#下载阿里源的文件
#centos7
wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo
#或者 curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo
sed -i -e '/mirrors.cloud.aliyuncs.com/d' -e '/mirrors.aliyuncs.com/d' /etc/yum.repos.d/CentOS-Base.repo

#清理本地缓存(可选)
#yum clean all

#更新软件源的本地缓存(本地缓存:源的软件列表和包的元数据,元数据:包的信息和包的依赖关系,包的信息:版本号、更新日期、作者、描述等)
yum makecache

参考:https://developer.aliyun.com/mirror/centos?spm=a2c6h.13651102.0.0.534d1b11Q4rbUO

yum 源配置说明:

  • [base] 容器名称,一定要放在[ ]中,从以上文件可以看出centos7默认配置有4个容器,一般是第一个起作用
  • name 容器说明,可以自己随便写
  • mirrorlist 镜像站点,这个可以注释掉
  • baseurl 我们的yum源服务器的地址。默认是CentOS官方的yum源服务器,是可以使用的,如果你觉得慢可以改成你喜欢的yum源地址
  • enabled 此容器是否生效,如果不写或写成enable=1都是生效,写成enable=0就是不生效
  • gpgcheck 如果是1是指RPM的数字证书生效,如果是0则不生效
  • gpgkey 数字证书的公钥文件保存位置。不用修改

安装 epel 源

1
2
3
4
5
6
7
8
9
yum install -y epel-release
yum makecache

#以上默认安装的 epel 源是国外的,速度比较慢,推荐改用国内的 epel 源(可选,推荐)
cd /etc/yum.repos.d/
mkdir backup
mv epel*.repo backup
wget -O epel.repo http://mirrors.aliyun.com/repo/epel-7.repo
yum makecache

参考:

(2)查询
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#根据关键字搜索可用软件包
yum search 关键字

#查询某个命令所属的安装包(命令所属的软件包安装或未安装都可以查询)
yum provides 命令路径 #如:yum provides */ifconfig


#列出所有可用软件包
yum list
#列出已安装的所有软件包
yum list installed
#列出已安装的指定软件包(可用于查看软件包是否已安装)
yum list installed <package-name> #或者 yum list | grep 关键字
##列出可更新的所有软件包
yum list updates

#查看安装包的信息(包括:名称、架构、版本、安装源、包大小、简介、描述等)
yum info <package-name>
(3)安装
1
2
3
#安装指定的软件包(选项:-y 自动回答yes)
#该命令安装包前会自动检测软件源的本地缓存,如果过期则会自动更新软件源的本地缓存,故而不需要再手动执行yum makecache命令
yum install <package-name>

默认情况下,yum install 在成功安装软件包后会自动删除下载的 rpm 软件包文件。如果需要获取 rpm 软件包文件可如下操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
#方式1:下载软件包
#如不指定下载路径,则默认下载路径为当前目录
#该命令下载软件包默认不会包括依赖包,如需依赖包则加选项:--resolve
yumdownloader --destdir=/path/to/directory <package-name>
yumdownloader --destdir=/path/to/directory --resolve <package-name>
#获得软件包URL地址
yumdownloader -q --urls <package-name>

#方式2:下载软件包
#如不指定下载路径,则默认下载路径为:/var/cache/yum/的子目录中,如centos764位系统为:/var/cache/yum/x86_64/7/updates/packages/
#该命令下载软件包会强制包括依赖包
#该命令只下载不安装
yum install --downloadonly --downloaddir=/path/to/directory <package-name>
(4)更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#升级更新指定的软件包(选项:-y 自动回答yes)
yum update <package-name>


#升级更新系统所有软件包(默认自动删除旧版包)
#是否自动删除旧版包由/etc/yum.conf配置文件的obsoletes决定,1表示更新旧的rpm包的同时会删除旧包,0表示更新的时候不会删除旧包,
yum update

#升级更新系统所有软件包(自动删除旧版包)
#yum upgrade等价于打开obsoletes配置的yum update
yum upgrade


#升级更新系统所有软件包并排除某些包的更新
#以下是单次更新时排除更新包,如果需要不加参数自动排除的话需要编辑/etc/yum.conf配置文件。在[main]的作用域内里加上这样一句话exclude=*NetworkManager*
yum --exclude=exclude=*NetworkManager*,*firewalld* update

💁‍♂ 提示:以上更新升级操作只是升级当前系统版本的软件包(包括内核版本,通常升级的默认内核版本一般都较低,如需升级更高版本的内核则需要手动安装)。需要说明的是不会升级系统的版本,如果要升级系统版本则需要使用新版本的系统镜像重装系统。

💁‍♂ 提示:更新升级常见失败问题:

如:yum update 出现 Multilib version problems 问题的解决方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
># 1、安装yum-complete-transaction
>yum install yum-utils
># 2、运行yum-complete-transaction
>yum-complete-transaction –cleanup-only
># 3、清除重复的包
>package-cleanup --dupes
>#清除重复包的老版本:
>package-cleanup --cleandupes
># 4、清除损坏的包
>package-cleanup --problems
>#5、解决依赖冲突:如出现:firewalld-filesystem-0.6.3-13.el7_9.noarch 有已安装冲突 firewalld < ('0', '0.3.13', None): firewalld-0.3.9-7.el7.noarch
># 查询出重复的软件包,会查出来两个包含版本的完整包名
>rpm -q 冲突的包名称
># 删除冲突包(一般是旧版本)
>rpm -e 包含版本的完整包名

>## 以下是示例:
># 查询重复的软件包(假设systemd-libs出现了冲突)
>$ rpm -q systemd-libs
>systemd-libs-219-30.el7.x86_64
>systemd-libs-219-42.el7_4.1.x86_64
># 删除旧版
>$ rpm -e systemd-libs-219-30.el7.x86_64
>error: Failed dependencies:
systemd-libs = 219-30.el7 is needed by (installed) libgudev1-219-30.el7.x86_64
># 仍然出现依赖问题,继续查询libgudev1的版本信息
>$ rpm -q libgudev1
>libgudev1-219-30.el7.x86_64
># 发现只有一个版本,升级试一下
>$ yum update libgudev1
>......
>Updated:
libgudev1.x86_64 0:219-42.el7_4.1
>Complete!
>$ rpm -q libgudev1
>libgudev1-219-42.el7_4.1.x86_64
># 升级完成后,删除旧版本的systemd-libs
>$ rpm -e systemd-libs-219-30.el7.x86_64
>$ rpm -q systemd-libs
(5) 卸载
1
2
3
4
5
6
7
8
#卸载指定的软件包
#提示:
#该命令会自动删除其依赖包中不再需要的依赖包(类似于:apt remove --auto-remove <package-name> )
#该命令默认情况下不会自动删除软件包的配置文件。如果希望删除则只能进行手动删除操作(配置文件通常位于/etc目录下)
yum remove -y <package-name>

#卸载系统中所有不再需要的依赖包
yum autoremove

💁‍♂ 提示:不再需要的依赖包是指不再被其他软件包所依赖的包。

(6)软件组安装卸载

组名可以由grouplist查询出来

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#列出所有可用的软件组
yum grouplist

#安装指定软件组
yum groupinstall 软件组名
#如:yum groupinstall "Development tools"

#卸载指定软件组
yum groupremove 软件组名

#清除已下载的软件包文件的缓存(可选)
#删除/var/cache/yum目录里所有软件源对应packages目录里的RPM包文件
#提示:与Debian系列系统不同,在Redhat系列系统中,通过yum安装或更新的软件,默认会自动删除掉RPM包缓存文件,而不会保留在缓存目录里。是否保留由/etc/yum.conf配置文件里的keepcache字段决定(1:保留,0:不保留,默认)
#yum clean packages

4. Snap 在线包管理器

1)安装 Snap

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
##(1)安装snapd
# apt安装(提示:ubuntu16.04之后的版本已经内置了snap,在debian系统上则需要手动安装)
apt update
apt install -y snapd

# yum安装(操作命令相对会多一些)
yum install -y epel-release
yum install -y snapd

##(2)启动snad的套接字单元
# 启动snapd套接字单元(注意套接字单元是snapd.socket,而不是snapd.service,其中snapd.service可简写为snapd)
systemctl enable --now snapd.socket #等同于 systemctl enable snapd.socket && systemctl start snapd.socket
# 查看是否成功启动snapd
systemctl status snapd.socket

##(3)需要注销并重新登录(重新打开终端即可)或重新启动系统以确保正确更新snap的路径

##(4)安装snap核心包
# 安装snap核心包
snap install core
snap refresh core

##(5)配置支持snap经典模式安装(仅yum安装snap时需要)
# 说明:由于snap经典模式安装需要操作/snap目录。通过yum安装snapd时,snap所安装的经典包存放在/var/lib/snapd/snap目录中而非/snap目录,所以需要创建一个符号链接/snap指向到/var/lib/snapd/snap,否则snap只能安装标准包而无法安装经典包。而使用apt安装snapd时,snap所安装的经典包就存放在/snap目录中,故而不需要创建符号链接。
ln -s /var/lib/snapd/snap /snap

Snap 安装参考:https://snapcraft.io/docs/installing-snapd

2)Snap 常用命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#搜索 Snap 软件包
snap find package-name

##安装标准的 Snap 软件包
#Snap 软件包通常是以沙箱方式运行的,这意味着它们受到严格的限制以增强安全性和隔离性。使用此命令安装的软件包将按照 Snap 的默认策略进行沙箱化。
snap install package-name

##安装经典 Snap 软件包
#经典 Snap 软件包是一种特殊类型的 Snap 软件包,它们不会受到严格的沙箱限制。它们可以访问系统上的更多资源和文件,因此更接近传统的非 Snap 软件包。这种类型的 Snap 软件包通常用于需要更多系统级访问权限的应用程序,比如开发工具或服务器软件。
snap install --classic package-name

#卸载 Snap 软件包
snap remove package-name

#列出已安装的 Snap 软件包
snap list

#更新所有已安装的 Snap 软件包
snap refresh

#查看 Snap 版本信息
snap version

#查看 Snap 软件包信息
snap info package-name

#管理 Snap 服务
snap enable service-name #启用 Snap 服务
snap disable service-name #禁用 Snap 服务
snap services #查看 Snap 服务

#管理 Snap 用户权限
snap connections package-name # 查看 Snap 软件包的连接信息
snap connect package-name:interface-name # 允许 Snap 软件包访问特定接口
snap disconnect package-name:interface-name # 禁止 Snap 软件包访问特定接口

3)卸载 Snap

1
2
3
4
5
6
7
8
9
10
11
12
13
#关闭snapd套接字单元(卸载前先停掉snapd套接字单元,否则卸载失败)
systemctl stop snapd.socket

##卸载snap
#1、yum卸载
yum remove -y snapd
#删除残余目录或文件
rm -rf /var/lib/snapd /snap ~/snap

#2、apt卸载
apt remove --purge -y snapd #如果不加--purge则需要手动删除/var/lib/snapd和/snap
#删除残余目录或文件
rm -rf ~/snap

5. 源码包安装卸载(待续···)

6. 通用更换系统软件源脚本(支持大部分 Linux 系统)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 中国大陆(默认)
# 执行命令后会交互式地提示选择软件源(可选源:阿里云、网易、清华大学源等)
bash <(curl -sSL https://linuxmirrors.cn/main.sh)
#或者:
#bash <(curl -sSL https://raw.githubusercontent.com/SuperManito/LinuxMirrors/main/ChangeMirrors.sh)

# 中国大陆教育网(可选源:清华大学、北京大学、南京大学等)
bash <(curl -sSL https://linuxmirrors.cn/main.sh) --edu

# 海外地区(可选源:亚洲|香港|xTom、北美|美国|Linux Kernel、欧洲|英国|Vorboss Ltd 等)
bash <(curl -sSL https://linuxmirrors.cn/main.sh) --abroad



##常见选项说明:
--abroad #使用海外软件源(选项值:无)
--edu #使用中国大陆教育网软件源(选项值:无)
--abroad #使用海外软件源(选项值:无)
--use-official-source #使用操作系统官方软件源(选项值:无)
--install-epel #安装 EPEL 附加软件包(选项值:true 或 false)
--only-epel #仅更换 EPEL 软件源模式(选项值:无)
--clean-cache #清理下载缓存(选项值:true 或 false)
#更多选项参考:https://linuxmirrors.cn/use/command-options/

适配 Linux 系统:Debian(8.0 ~ 13)、Ubuntu(14.04 ~ 24)、CentOS(7.0 ~ 8.5 / Stream 8 ~ 9)、 Rocky Linux(8 ~ 9)、Deepin(all)等

参考:

七、进程管理

所谓 进程,通俗地说就是当前正在执行的一个程序。

1. 列出当前进程信息 ps

1
2
3
4
5
6
7
8
9
10
11
12
#列出当前进程信息
#-a或者-e:显示终端上的所有进程,包括其他用户的进程;-u:显示进程的详细状态;-x:显示没有控制终端的进程;-f:显示程序间的关系
ps -aux
ps -ef

#根据进程号查看进程的文件路径、启动命令的完整路径等等信息(比如nginx)
ps -ef | grep nginx
ls -l /proc/10383
#有几个主要的文件我们可以关注下:
#cwd:文件所在目录
#exe:执行命令的完整路径
#environ:执行命令时的环境变量

提示:ps 默认只会显示当前用户通过终端启动的应用程序。

ps 命令主要显示的信息:

  • PID:进程 ID,每个进程都有一个唯一的 PID。
  • TTY:与进程关联的终端设备或伪终端。
  • TIME:已经使用的 CPU 时间(或者启动时间),显示该进程占用 CPU 的时间量。
  • CMD:命令名称或完整的命令行。

选项说明:

  • -a:显示所有用户的进程。这包括与终端关联的进程以及与其他用户关联的进程。
  • -x:显示没有控制终端的进程。
  • -u:显示指定用户的进程信息
  • -e:显示系统中所有的进程
  • -f:显示完整的格式,包括命令行
  • -l:使用长格式显示进程信息
  • aux:显示系统中所有用户的所有进程

2. 查看系统内存使用情况 free

1
2
3
#显示系统的内存使用情况
#以更易读的方式展示出来。参数 -h 用于以人类可读的格式显示输出,例如以 GB、MB 等为单位。
free -h

3. 系统负载监控 top

可实时查看系统的 CPU 使用率、内存使用量(含 Swap 虚拟内存使用量)、进程列表(程序允许命令)等,

1
2
3
4
5
#top 与 ps 命令很相似。它们都用来显示正在执行的进程。Top 与 ps 最大的不同之处,在于top 在执行一段时间可以更新正在运行的的进程。
#要退出可以直接输入q
top
#每隔10秒自动更新
top -d 10

常用的 top 快捷键:

切换排序

  • P(即:Shift + p):按 CPU 使用率进行排序
  • M(即:Shift + m):按内存使用量进行排序(按 e 键可以调整内存占用单位,比如以 MB 或 GB 为单位展示会更人性化 )

进程操作

  • k:杀死一个进程(需要输入相应的 PID)
  • r:更改进程的优先级

布局和显示

  • f:打开字段管理器,可以选择要显示的字段
  • o:更改排序字段
  • b:切换是否显示底部摘要信息

全局操作

  • q:退出 top 命令

4. 通过监听端口查询对应进程信息

1
2
3
4
5
6
7
8
##使用 netstat 命令来查看端口的对应进程信息(如:名称、PID 等)
#-tuln 选项用于显示 TCP 和 UDP 监听状态的端口
netstat -tuln | grep <port>

##使用 lsof 命令来查看端口的占用情况
apt install lsof # Debian/Ubuntu
yum install lsof # Red Hat/CentOS
lsof -i :<port>

5. 终止进程 kill

1
2
#-9表示强行终止
kill [-9] 进程代号

提示:使用 kill 命令时,最好只终止由当前用户开启的进程,而不要终止 root 身份开启的进程,否则可能导致系统崩溃。

6. 通过 PID 找出进程的对应文件路径

1
2
3
4
5
6
7
8
ls -l /proc/<port>/exe


#示例(查询 sshd 服务的 PID,然后通过 PID 查询出 sshd 的完整文件路径):
$ ps -ef | grep sshd
#root 14368 1 0 08:21 ? 00:00:00 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups
$ ls -l /proc/14368/exe
#lrwxrwxrwx 1 root root 0 Jan 19 03:45 /proc/14368/exe -> /usr/sbin/sshd

7. 查看命令路径 which

1
2
3
4
5
which 命令名称

#例如:
$ which useradd
/usr/sbin/useradd

Linux 中,绝大多数可执行文件都是保存在 /bin/sbin/usr/bin/usr/sbin

  • /binbinary)是二进制执行文件目录,主要用于具体应用
  • /sbinsystem binary)是系统管理员专用的二进制代码存放目录,主要用于系统管理
  • /usr/binuser commands for applications)后期安装的一些软件
  • /usr/sbinsuper user commands for applications)超级用户的一些管理程序

提示:cd 这个终端命令是内置在系统内核中的,没有独立的文件,因此用 which 无法找到 cd 命令的位置

8. 查看进程树 pstree

1
2
3
4
5
6
7
8
#安装pstree安装包
apt install psmisc
#yum install psmisc

#-p :显示进程的PID -u :显示进程的所属用户
#树状的形式显示进程和pid
pstree -p
#树状的形式进程和对应操作用户

image-20240116031624714

9. 系统监控实用工具

1)iftop

iftop可测量通过每一个套接字连接传输的数据。iftop使用pcap库来捕获进出网络适配器的数据包,然后汇总数据包大小和数量,搞清楚总的带宽使用情况。

虽然iftop报告每个连接所使用的带宽,但它无法报告参与某个套按字连接的进程名称/编号(ID)。不过由于基于pcap库,iftop能够过滤流量,并报告由过滤器指定的所选定主机连接的带宽使用情况。

1
2
3
4
5
#安装
apt install iftop
#yum install iftop
#使用
iftop -n

n选项可以防止iftop将IP地址解析成主机名,解析本身就会带来额外的网络流量。

image-20240116031546216

2)nload

nload是一个命令行工具,让用户可以分开来监控入站流量和出站流量。它还可以绘制图表以显示入站流量和出站流量,视图比例可以调整。用起来很简单。

1
2
3
4
5
#安装
apt install nload
#yum install nload
#使用
nload

image-20240116031407371

3)htop

htop是top的扩展版本,有更丰富的概貌(例如全命令、可视化、图形用户界面gui和用户界面ui),有鼠标点击交互(译者注:看下面的截图,指的是最上面的列标题如CPU%、MEM%等可以通过鼠标点击切换以显示不同的功能),也有许多的指导教你如何做进程管理。

1
2
3
4
5
#安装
apt install htop
#yum install htop
#运行
htop

image-20240116031200476

4)iotop

iotop – 简单的类似top的I/O监控器。

iotop是IO实时监控器。使用它们附属的详细输入输出(IO)使用方法可以展示出你系统中每个进程线程的信息。

该命令可以与$ tcpdump(响应网络流量的命令)一起使用。如果你发现你的web服务器上有程序在运行,你可以,比如运行$ tcpdump port 80检查端口80(标准的http端口)的网络流量来观察细节。

最有用的信息可能是DISK WRITE这一列,从该列你可以准确的看到每个IO使用了多少个进程,单位为K/s。

1
2
3
4
5
#安装
apt install iotop
#yum install iotop
#运行
iotop

image-20240116031221046

5)glances

glances是一款由python开发的系统监控工具,可以实时查看CPU、内存、网络、IO、进程、磁盘空间使用率的使用情况,并且支持三种运行模式,个人感觉比top命令使用更便捷,有三种运行模式:Standalone、Client/Server、Web server。

安装

多种安装方式可选,如下:

1
2
3
4
5
6
7
8
#yum 安装
yum -y install glances
#apt 安装
apt install glances #提示:如果 Debain 无法找到软件包,需添加 bullseye-backports 源
#pip 安装
pip install --user 'glances[all]'
#一键脚本安装
curl -L https://bit.ly/glances | /bin/bash

参考:https://github.com/nicolargo/glances

Standalone 模式

img

可以查看系统运行详细情况。

img

在运行glances时可以使用h键来查看glances快捷键使用方法。

img

运行过程中,直接按回车键可以对进程进行过滤,查看指定进程。

Client / Server 模式

Server端:glances -s -B 192.168.1.1
Client端:glances -c 192.168.1.1

无须去指定服务器上运行,通过Client/Server端模式快速查看。-B:指定绑定的IP地址,如果不指定Server端运行端口默认端口为:61209,如果使用默认端口则用-c指定客户端时不需要额外使用-P参数来指定Server端的端口号。需要注意的是防火墙设置,确认两台主机之间端口可通。

Web server 模式

glances -w
img

img

这个功能就很贴心了,我可以将集群中所有服务器上后台运行Web Server端,后续防火墙开放指定IP查看集群中服务器的运行状态,美滋滋。

如果启动Web Server端时出现**“Bottle module not found. Glances cannot start in web server mode.”**报错,执行安装bottle即可解决。

1
pip install bottle
配置文件

glances是支持设置配置文件的,但是不一定要有配置文件才能使用glances,Linux中配置文件可以新建位置到/etc/glances/glances.conf,窗口中的不同颜色是由阈值来设定的,我们可以在配置文件中修改各监控项的阈值来实现不同级别不同颜色的展示情况。

颜色级别定义
  • 绿色:正常(OK)
  • 蓝色:小心(CAREFUL),需要注意
  • 紫色:警告(WARNING)
  • 红色:问题严重(CRITICAL)
配置文件示例
1
2
3
4
5
6
7
8
9
10
11
vim /etc/glances/glances.conf
[quicklook]
cpu_careful=50
cpu_warning=70
cpu_critical=1
mem_careful=50
mem_warning=1
mem_critical=90
swap_careful=1
swap_warning=70
swap_critical=90

这里我们为了展示出颜色的差异,特别修改了几个为1的值,实际使用中修改到需要的值即可。
img

最终展示界面如上图所示。

八、系统管理

1. 关机和重启

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# shutdown命令可用于关闭或重启系统(-r表示重启,不指定则表示1分钟后自动关闭系统)
shutdown [-r] [时间]
# 例如:
#不指定-r则表示1分钟后自动关闭系统
shutdown
# 重新启动操作系统,其中 now 表示现在
shutdown -r now
# 立刻关机,其中 now 表示现在
shutdown now
# 系统在今天的 20:25 会关机
shutdown 20:25
# 系统再过十分钟后自动关机
shutdown +10
# 取消之前指定的关机计划
shutdown -c

# reboot命令可用于重启系统
reboot #等效于shutdown -r now

2. 查看系统配置

查看CPU信息:

  • 使用lscpu命令可以显示有关CPU架构和相关信息。
  • 使用cat /proc/cpuinfo命令可以查看更详细的CPU信息。

查看内存信息:

  • 使用free -h命令可以查看系统中的内存使用情况。
  • 使用cat /proc/meminfo命令可以获取更多的内存详细信息。

查看磁盘信息:

  • 使用df -h命令可以查看系统中各个磁盘分区的使用情况。
  • 使用lsblk命令可以显示磁盘和分区的详细信息。

3. 环境变量

简要概述

在 Linux 操作系统中设置环境变量,通常使用export 命令来实现。它可以将一个或多个变量从本地 shell (命令行解释器)的环境传递到子进程的环境中,以便让这些子进程也可以使用这些变量。在 Linux 中,每个进程都有一组环境变量。这些变量存储在进程空间中,并且可以在运行时由进程读取和修改。当您启动一个新的 shell 会话或者在当前 shell 会话中运行一个新的脚本时,该会话会继承父 shell 的环境变量。然而,如果您希望将变量传递给子进程,那么您需要将其标记为“导出”。

💁‍♂ 变量和环境变量的区别:

变量是 Shell 编程中最基本的元素之一。它们是用户定义的名称,用于保存一个或多个值或字符串,并在 Shell 脚本或命令中进行引用。变量的值可以是数字、字符串、文件名、路径名等。

例如,在 Bash shell 中,您可以通过以下语法来定义变量:

1
name="Alice"

这将创建一个名为 name 的变量,并将其设置为 “Alice”。

环境变量是 Shell 环境中的特殊类型的变量,它们具有全局范围并可以被所有子进程访问。环境变量通常用于存储 Shell 和其他程序所需的共享信息,例如路径、语言设置、用户信息等。

例如,在 Bash shell 中,您可以使用以下语法来设置环境变量:

1
export PATH=$PATH:/usr/local/bin

这会将 /usr/local/bin 目录添加到系统的 PATH 环境变量中,以便 Shell 可以搜索该目录中的可执行文件。

因此,变量和环境变量具有不同的作用和范围,并且通常用于不同的目的。

在 Linux 中设置环境变量的方法有多种,下面将主要讲其中两种常见的方法。

临时设置环境变量

要在当前 shell 会话中设置一个临时环境变量,可以使用 export 命令。例如,要将 MY_VAR 的值设置为 my_value,可以执行以下命令:

1
export MY_VAR=my_value

这将在当前 shell 会话中设置一个名为 MY_VAR 的环境变量,并将其值设置为 my_value。该变量只在当前会话中有效,关闭终端窗口或重启系统后就会自动清除。

永久设置环境变量

要在系统中永久设置一个环境变量,可以将其添加到 ~/.bashrc~/.bash_profile/etc/profile 等脚本文件中,这样系统在某个特定情况下将会自动执行这些脚本以让脚本里设置的环境变量生效。

下面以添加环境变量到~/.bashrc脚本文件为例讲解配置过程:

1
2
3
4
5
6
7
8
9
10
#在文件最后加入变量
cat >> ~/.bashrc << 'EOF'
export MY_VAR=my_value
EOF

#使配置文件修改生效
source ~/.bashrc

#测试
echo $MY_VAR

💁‍♂ /etc/profile 等脚本文件说明:

  • ~/.bashrc:打开新的 Bash shell 会话时自动执行该脚本。该文件只适用于当前用户的 Bash shell,通常用于设置用户环境变量等配置。
  • ~/.bash_profile:如果系统默认shell是bash,用户登录时将自动执行该脚本。该文件只适用于当前用户的 Bash shell,通常用于设置用户环境变量等配置。
  • /etc/profile:在系统引导时自动执行该脚本。该文件适用于所有用户和所有 Bash shell,通常用于设置全局环境变量等配置。

💁‍♂ 注意:只要执行bash命令就会打开新的 Bash shell 会话。

💁‍♂ 总结:开机启动系统,在系统引导时将自动执行/etc/profile脚本文件。等系统启动完成后用户就可以进行登录操作了,如果系统默认shell是bash,那么在用户登录时系统会自动执行bash命令来打开新的 Bash shell 会话,故而会自动执行~/.bash_profile~/.bashrc脚本文件。但如果系统默认shell是sh、zsh等其他类型的shell,那么登录时将不会自动执行~/.bash_profile脚本,但当用户手动执行bash命令时是会自动执行~/.bashrc脚本文件的。

💁‍♂ 建议:在 Linux 中,虽然~/.bashrc~/.bash_profile/etc/profile 等脚本文件都能配置环境变量,但通常使用的话建议将环境变量配置到 ~/.bashrc 文件中。

4. 系统版本和内核版本

1)查看系统版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
##(1)通过 lsb_release 命令查看方式
#安装依赖
apt install lsb-release #Debian 系列系统(如:Debian、Ubuntu 等)
yum install redhat-lsb-core #Red Hat 系列系统(如:CentOS、Fedora 等)
#查看系统版本(通用,含系统名称、系统版本号、版本代号、描述等)
lsb_release -a


##(2)通过系统配置文件查看方式
#查看系统版本(通用,含系统名称(ID)、系统版本号、版本代号、描述等)
cat /etc/os-release


#仅查看系统名称(ID)
cat /etc/os-release | grep -oP '^ID=\K\S+'

#仅查看系统版本号
cat /etc/os-release | grep VERSION_ID | cut -d '=' -f 2 | sed 's/"//g'

#仅查看系统版本代号
cat /etc/os-release | grep VERSION_CODENAME | cut -d '=' -f 2
#cat /etc/os-release | grep VERSION_CODENAME | awk -F '=' '{print $2}'
#cat /etc/os-release | grep VERSION_CODENAME | sed 's/.*=//'

2)查看内核版本

1
uname -r

3)升级内核版本

简要说明

通过系统默认官方源在线升级的内核版本一般都不会太新,特别是一些老版本的系统(如:CentOS 7、Ubuntu 18.04 等)。由于为了让系统稳定,通常 Linux 发行商官方都会选择一些经过长期测试和使用的老版本内核,所以官方的软件源都不会提供太新的内核版本,如果非要使用更高版本的内核则应该通过其他方式安装升级,主要为如下几种方式:

  • 下载 Linux 新版内核进行编译安装
  • 使用第三方源进行在线安装(如:elrepo 源、XanMod 源等)
  • 使用已编译好的二进制包进行安装(建议通过一键脚本安装)

温馨提示:使用非官方源安装的内核可能会导致系统不稳定,非必要情况当然更推荐使用官方源支持的内核版本,通常更高版本内核在对应 LInux 新版本中会得到更新的支持(如 Ubuntu 22.04 的官方源内核版本会比 Ubuntu 18.04 更新,如需更新内核版本应该考虑升级系统版本)。

参考:

方式一:通过系统默认官方源在线升级的内核版本

这种方式升级的版本为系统发行方维护的版本,通常版本较低

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
##(1)CentOS/RedHat
#更新内核版本
yum update kernel
#更新引导加载程序(必选,即设置使用新版内核启动,CentOS/RedHat 安装新版内核不会自动更新引导加载程序为最新内核)
#如果需要使用其他版本内核可通过执行:egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \' 命令查看已安装所有版本内核顺序(从0开始,默认最高版本在最前面)
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg #用于传统的BIOS引导
#grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg #用于UEFI引导(如果使用的是 UEFI 引导,则应该更新的是 UEFI GRUB 配置)
#重启服务器以使新版内核生效(必选)
reboot
##删除无用的旧内核版本(可选,为了节省磁盘空间建议删除)
#查看已安装的所有内核版本
rpm -qa kernel kernel-*
#确认当前正在使用的内核
uname -r
#删除不需要的内核版本(将 <kernel-package> 替换为要删除的包名)
yum remove <kernel-package>
#更新引导加载程序配置(如果使用 GRUB 引导)
grub2-mkconfig -o /boot/grub2/grub.cfg


##(2)Ubuntu/Debian
#列出可升级内核版本
apt list --upgradable | grep linux-image
#安装支持的新版内核
apt install linux-image-generic
#apt install linux-generic-hwe-18.04-edge #对于Ubuntu,在版本系统中可以安装指定系统版本(如Ubuntu 18.04)的hwe内核包,其版本通常比默认内核包版本高,但可能不稳定
#更新引导加载程序(可选,即设置使用新版内核启动,Ubuntu/Debian 安装新版内核会自动更新引导加载程序为最新内核)
#通常情况下,新内核的 GRUB 引导项会自动成为默认的引导项。
#如果需要使用其他版本内核可通过执行:grep 'menuentry' /boot/grub/grub.cfg 命令查看已安装所有版本内核顺序(从0开始,默认最高版本在最前面),然后修改 /etc/default/grub 中的 GRUB_DEFAULT 值(设要修改的内核索引顺序为 2,则修改为:GRUB_DEFAULT="1> 2"),最后执行 update-grub 并 reboot 重启系统即可。参考:https://www.cnblogs.com/zzugyl/p/14588114.html
#关机重启时一般会进入grub菜单,在菜单中可以选择指定版本的内核启动,如果启动时跳过不展示grub菜单,则可以在启动时按住Shift键或Esc键,直到出现GRUB菜单。
update-grub
#重启服务器以使新版内核生效(必选)
reboot
##删除无用的旧内核版本(可选,为了节省磁盘空间建议删除)
#查看已安装的所有内核版本
dpkg --list | grep linux-image
#确认当前正在使用的内核
uname -r
#删除不需要的内核版本(将 <kernel-package> 替换为要删除的包名)
apt purge <kernel-package>
#更新引导加载程序配置
update-grub
方式二:使用第三方源在线安装较新版本的内核
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
##(1)CentOS/RedHat
#参考:http://elrepo.org/tiki/HomePage、https://www.cccitu.com/oos583vx2.html
#安装 elrepo 第三方软件源
yum install -y elrepo-release
#rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org #导入公钥
#yum install https://www.elrepo.org/elrepo-release-7.el7.elrepo.noarch.rpm #安装 CentOS7/RedHat7 的 elrepo 源
#yum install https://www.elrepo.org/elrepo-release-8.el8.elrepo.noarch.rpm #安装 CentOS8/RedHat8 的 elrepo 源
#查看可更新内核版本
yum --disablerepo="*" --enablerepo="elrepo-kernel" list available
#安装最新版本内核(elrepo源有ml、lt两种内核。ml(mainline)为最新版本的内核,lt为长期支持的内核。)
yum --enablerepo=elrepo-kernel install -y kernel-lt
#更新引导加载程序(必选,即设置使用新版内核启动,CentOS/RedHat 安装新版内核不会自动更新引导加载程序为最新内核)
#如果需要使用其他版本内核可通过执行:egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \' 命令查看已安装所有版本内核顺序(从0开始,默认最高版本在最前面)
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg #用于传统的BIOS引导
#grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg #用于UEFI引导(如果使用的是 UEFI 引导,则应该更新的是 UEFI GRUB 配置)
#重启服务器以使新版内核生效(必选)
reboot
##删除无用的旧内核版本(可选,为了节省磁盘空间建议删除)
#查看已安装的所有内核版本(仅含yum或rpm管理器安装的包,不含手动编译安装的包)
rpm -qa kernel kernel-*
#确认当前正在使用的内核
uname -r
#删除不需要的内核版本(将 <kernel-package> 替换为要删除的包名)
yum remove <kernel-package>
#更新引导加载程序配置(如果使用 GRUB 引导)
grub2-mkconfig -o /boot/grub2/grub.cfg

##(2)Ubuntu/Debian
#参考:https://xanmod.org
#安装 XanMod 源
wget -qO - https://dl.xanmod.org/archive.key | gpg --dearmor -o /usr/share/keyrings/xanmod-archive-keyring.gpg
echo 'deb [signed-by=/usr/share/keyrings/xanmod-archive-keyring.gpg] http://deb.xanmod.org releases main' | tee /etc/apt/sources.list.d/xanmod-release.list
#安装最新版本内核
apt update
apt install linux-xanmod-x64v3
#更新引导加载程序(可选,即设置使用新版内核启动,Ubuntu/Debian 安装新版内核会自动更新引导加载程序为最新内核)
#通常情况下,新内核的 GRUB 引导项会自动成为默认的引导项。
#如果需要使用其他版本内核可通过执行:grep 'menuentry' /boot/grub/grub.cfg 命令查看已安装所有版本内核顺序(从0开始,默认最高版本在最前面),然后修改 /etc/default/grub 中的 GRUB_DEFAULT 值(设要修改的内核索引顺序为 2,则修改为:GRUB_DEFAULT="1> 2"),最后执行 update-grub 并 reboot 重启系统即可。参考:https://www.cnblogs.com/zzugyl/p/14588114.html
#关机重启时一般会进入grub菜单,在菜单中可以选择指定版本的内核启动,如果启动时跳过不展示grub菜单,则可以在启动时按住Shift键或Esc键,直到出现GRUB菜单。
update-grub
#重启服务器以使新版内核生效(必选)
reboot
##删除无用的旧内核版本(可选,为了节省磁盘空间建议删除)
#查看已安装的所有内核版本
dpkg --list | grep linux-image
#确认当前正在使用的内核
uname -r
#删除不需要的内核版本(将 <kernel-package> 替换为要删除的包名)
apt purge <kernel-package>
#更新引导加载程序配置
update-grub
方式三:使用已编译好的二进制包进行安装
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#这里使用一键脚本安装方式
#脚本项目地址:https://github.com/ylx2016/Linux-NetSpeed
#原功能是一键安装 BBR/BBRplus/锐速,可用于升级系统内核
#支持 CentOS 7/8,Debian/Ubuntu,OracleLinux
#在国内执行脚本时可能无法正常下载新版内核等文件,故需要挂代理,并执行如下命令:
# export http_proxy=http://192.168.31.74:1081
# export https_proxy=http://192.168.31.74:1081
#安装新版内核只需要选择 1. 安装 BBR原版内核,脚本会自动卸载旧版内核并安装最新版内核
#下载脚本
wget -O tcp.sh "https://github.com/ylx2016/Linux-NetSpeed/raw/master/tcp.sh"
#执行脚本
chmod +x tcp.sh
./tcp.sh
#删除脚本(升级完成内核后可选择删除脚本)
rm -f ./tcp.sh
方式四:下载内核源码手动编译安装

这种方式可安装最新版或任意版本内核。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#1、安装依赖
#Debian 系列系统安装所需依赖
apt update
apt install build-essential #包含 make、gcc、g++ 等基础编译工具
apt install libncurses-dev bison flex libssl-dev libelf-dev dwarves bc

#RedHat 系列系统安装所需依赖
yum groupinstall "Development Tools" #包含 make、gcc、g++ 等基础编译工具
yum install ncurses-devel flex bison openssl openssl-devel elfutils-libelf-devel bc

#2、下载指定版本的内核源码并解压
#到 Linux 内核官网 https://www.kernel.org 下载指定版本的内核源码包,建议下载 stable(稳定版)或者 longterm(长期维护版)
#可使用代理下载:wget -e "https_proxy=http://192.168.31.74:1081" https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.5.8.tar.xz
wget https://cdn.kernel.org/pub/linux/kernel/v6.x/linux-6.5.8.tar.xz
tar xvf linux-6.5.8.tar.xz
cd linux-6.5.8

#3、配置所编译的内核(交互式操作生成编译配置文件.config)
#centos7 等 yum 默认安装的 gcc 版本太低可能无法编译新内核,则需要手动安装更新 gcc 版本,建议使用 scl 工具管理多版本 gcc,参考:https://cloud.tencent.com/developer/article/1626791
#包括驱动、网络、文件系统等等
#勾选说明:* 表示为编译到内核镜像(主要生成的文件如:arch/x86/boot/bzImage、vmlinux 等),M 表示编译到内核模块,空表示不编译。(内核模块的作用是启动内核镜像时按需从镜像文件外部加载内核模块,这样可以有效减小内核镜像的大小和启动时间)
#通常执行该命令时会自动参考当前系统内核(即原版本内核,当前系统内核配置:/boot/config-<当前系统内核>)自动勾选配置,也就是说原版本内核有的功能或模块在编译选项里将会被勾选,而如果原本没有则不会自动勾选。故而即使是同一个版本的内核源码在不同内核的 Linux 系统中所展示的默认配置勾选也可能不同。
# 1)通常使用原版本内核默认勾选的功能配置即可。
# 2)编译的内核通常都默认带有调试信息,那么内核和模块的文件将会很大,占用很多磁盘空间。建议去除这些内核调试信息,可有效减小内核模块和内核大小,节省存储空间。菜单导航:Kernel hacking -> Compile-time checks and compiler options -> Debug information (Disable debug information) -> Disable debug information inking,按空格选择设置为 X 表示关闭调试信息,然后选择 Save -> OK
# 3)如果原本的系统内核功能不满足需求则需要额外勾选配置,常见功能如下:
#(1)TCP BBR:需要内核为 4.9+,菜单导航:Networking support -> Networking options -> TCP: advanced congestion control -> BBR TCP,按空格选择设置为 M 表示编译到内核模块,然后选择 Save -> OK
#(2)WireGuard:需要内核版本为 5.6+,菜单导航:Device Drivers -> Network device support -> Network core driver support -> WireGuard secure network tunnel,按空格选择设置为 M 表示编译到内核模块,然后选择 Save -> OK
#自定义内核版本名称(可选,如:linux-6.5.8-test,默认为内核原始版本号,如:6.5.8),菜单导航:General setup -> Local version - append to kernel release,输入自定义的内核版本名称并保存即可
# 4)菜单勾选确定后,选择 Exit 退出,选择 YES 保存配置到当期目录的 .config 文件里。
make menuconfig

#4、编译内核
#根据 .config 配置文件选择性进行编译
#可使用 -j 指定线程数加快编译,或者通过处理器核心数指定线程数:make -j$(nproc)
#如果之前编译过,再编译则会很快
#可以通过 make clean 清理编译生成的临时文件(或者使用 make mrproper,区别是 make mrproper 会删除 .config 文件,而 make clean 不会)
#内核编译时间通常都会比较久(通常需要几个小时,差不多2-3小时左右,计算机配置越高编译会越快,主要是CPU,如果使用虚拟机,最好分配多点核心数,如4个)
#注意通常要求系统的磁盘剩余空间不低于 25G,否则编译产生的临时文件可能太多导致磁盘不够用而编译失败,建议总磁盘大小 40G 以上,当然,对于精简配置或者去除调试信息的情况对磁盘空间要求更低(如除调试信息的情况就只需要 10G 左右大小的磁盘剩余空间即可)。参考:https://forums.debiancn.org/t/topic/3120
make -j4


#5、安装内核
make modules_install #安装内核模块(将相应的内核模块复制到系统/lib/modules/<version>目录里)
make install #安装内核镜像(将.config,vmlinuz,initrd.img(make install时会自动用mkinitramfs生成),System.map复制到系统/boot目录里,得到vmlinuz-<version>、initrd.img-<version>、System.map-<version>、config-<version>)

#6、更新引导加载程序配置
#(1)Ubuntu/Debian
#更新引导加载程序(可选,即设置使用新版内核启动,Ubuntu/Debian 安装新版内核会自动更新引导加载程序为最新内核)
#通常情况下,新内核的 GRUB 引导项会自动成为默认的引导项。
#如果需要使用其他版本内核可通过执行:grep 'menuentry' /boot/grub/grub.cfg 命令查看已安装所有版本内核顺序(从0开始,默认最高版本在最前面),然后修改 /etc/default/grub 中的 GRUB_DEFAULT 值(设要修改的内核索引顺序为 2,则修改为:GRUB_DEFAULT="1> 2"),最后执行 update-grub 并 reboot 重启系统即可。参考:https://www.cnblogs.com/zzugyl/p/14588114.html
#关机重启时一般会进入grub菜单,在菜单中可以选择指定版本的内核启动,如果启动时跳过不展示grub菜单,则可以在启动时按住Shift键或Esc键,直到出现GRUB菜单。
update-grub

#(2)CentOS/RedHat
#更新引导加载程序(必选,即设置使用新版内核启动,CentOS/RedHat 安装新版内核不会自动更新引导加载程序为最新内核)
#如果需要使用其他版本内核可通过执行:egrep ^menuentry /etc/grub2.cfg | cut -f 2 -d \' 命令查看已安装所有版本内核顺序(从0开始,默认最高版本在最前面)
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg #用于传统的BIOS引导
#grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg #用于UEFI引导

#7、启服务器以使新版内核生效(必选)
reboot


#8、卸载编译安装的内核(如需要)
#将 <version> 替换为对应内核版本号
#删除内核映像文件
rm /boot/vmlinuz-<version>
rm /boot/initrd.img-<version>
rm /boot/System.map-<version>
rm /boot/config-<version>
#删除模块文件
#提示:实际模块文件在 /usr/lib/modules 目录里,由于 /lib 目录是 /usr/lib 目录的符号链接,故可以通过删除 /lib 里的内容从而实现删除 /usr/lib 里的内容
rm -r /lib/modules/<version>
##更新引导加载程序配置
#Debian 系列系统更新引导加载程序配置(可选)
update-grub
#RedHat 系列系统更新引导加载程序配置(必选)
grub2-set-default 0
grub2-mkconfig -o /boot/grub2/grub.cfg #用于传统的BIOS引导
#grub2-mkconfig -o /boot/efi/EFI/centos/grub.cfg #用于UEFI引导
#重启
reboot

提示:

(1)Ubuntu 编译报错提示:make[2]: *** No rule to make target 'debian/canonical-certs.pem', needed by 'certs/x509_certificate_list'(注意这个报错提示可能是出现在上文,应该终端中搜索查询一下),解决办法如下:

1
2
3
4
>scripts/config --set-str SYSTEM_TRUSTED_KEYS ""
>scripts/config --set-str SYSTEM_REVOCATION_KEYS ""

>##对于Ubuntu,最好在 make menuconfig 执行完成后进行如上操作,防止编译报错

以上命令执行后,然后重新编译。

参考:https://askubuntu.com/questions/1329538/compiling-the-kernel-5-11-11。

(2)Ubuntu 编译安装内核完成并重启后,出现错误:end Kernel panic - not syncing: System is deadlocked on memory,这个原因通常是因为编译的内核过大,需要更多的内存加载。

  • 临时解决方法:在虚拟机选项中将内存改大一些,我改成 4GB 再重启就可以了。
  • 彻底解决办法:减小内核大小,通常是去除内核的调试信息即可。

(3)编译的内核通常都默认带有调试信息,那么内核和模块的文件将会很大,占用很多磁盘空间。去除这些内核调试信息,可有效减小内核模块和内核大小,节省存储空间。实现方式如下:

方式1:如果尚未编译,则可以在 make menuconfig 时,在交互菜单界面中选择关闭调试信息,菜单导航:Kernel hacking -> Compile-time checks and compiler options -> Debug information (Disable debug information) -> Disable debug information inking,按空格选择设置为 X 表示关闭调试信息,然后选择 Save -> OK

方式2:如果尚未编译,则可以在 make menuconfig 生成.config 文件后,修改其调试参数来去除调试信息,然后再编译。(这种方式编译出来的内核和模块都会占用更小的空间)

1
2
3
4
5
6
7
8
>scripts/config --undefine GDB_SCRIPTS
>scripts/config --undefine DEBUG_INFO
>scripts/config --undefine DEBUG_INFO_SPLIT
>scripts/config --undefine DEBUG_INFO_REDUCED
>scripts/config --undefine DEBUG_INFO_COMPRESSED
>scripts/config --set-val DEBUG_INFO_NONE y
>scripts/config --set-val DEBUG_INFO_DWARF5 n
>scripts/config --disable DEBUG_INFO_DWARF_TOOLCHAIN_DEFAULT

参考:https://superuser.com/questions/925079/compile-linux-kernel-deb-pkg-target-without-generating-dbg-package

方式3:如果已经编译得到带有调试信息的内核和模块了,那么可以在安装内核和内核模块时加上 INSTALL_MOD_STRIP=1 参数来剥离调试信息,减小内核模块和内核大小,节省存储空间。

1
2
3
>#安装时指定 INSTALL_MOD_STRIP=1 可剥离调试信息,减小内核模块和内核大小,节省存储空间
>make INSTALL_MOD_STRIP=1 modules_install
>make INSTALL_MOD_STRIP=1 install

(4)更多问题和解决办法:https://blog.51cto.com/u_15127511/4320481

参考

5. 服务管理

1)服务相关概念

服务(service) 是一种开机自启动的后台运行程序,也称为守护进程(运行中的程序就叫进程)。通常会在系统启动时自动运行,并一直保持运行状态,以便用户和其他程序可以随时使用。常见的服务程序有 sshd、mysqld、httpd 等。

💁‍♂ 程序的运行模式:

计算机程序的运行模式是指程序在计算机系统中的运行方式和状态。根据程序的运行模式不同,可以分为以下几种:

  1. 前台模式

前台模式(Foreground Mode)是指程序需要在用户界面上显示输出信息,等待用户输入或响应操作的模式。这些程序运行时会占用当前终端或图形界面的屏幕空间,并且随着用户的注销或关闭终端而结束。例如,文本编辑器、Web 浏览器、音乐播放器等都是前台模式下运行的程序。

  1. 后台模式

后台模式(Background Mode)是指程序不需要在用户界面上显示输出信息,它们会在系统后台默默地执行任务,不会占用当前终端或图形界面的屏幕空间,并且在用户注销或关闭终端时仍然可以继续运行。例如,服务程序、守护进程、定时任务等都是后台模式下运行的程序。

  1. 守护进程模式

守护进程模式(Daemon Mode),也称为服务模式(Service Mode),是一种特殊的后台模式,在系统启动时自动启动并一直保持运行状态,以提供某种特定的服务或功能。守护进程通常会监听某个网络端口或 Unix 套接字,等待客户端连接并处理请求。例如,Web 服务器、数据库服务器、邮件服务器等都是守护进程模式下运行的程序。

  1. 嵌入式模式

嵌入式模式(Embedded Mode)是指程序被嵌入到其他程序或系统中执行,以完成特定的任务或提供服务。嵌入式模式下运行的程序通常具有轻量化、高效性和实时性等特点,例如,操作系统内核、驱动程序、嵌入式应用程序等都是嵌入式模式下运行的程序。

总之,计算机程序的运行模式与程序本身的功能、特点和用途密切相关。不同的运行模式可以满足不同的需求和场景,理解这些运行模式对于程序设计、开发和管理都有重要作用。

💁‍♂ 关于服务程序的补充说明:

应用程序是否为服务程序,取决于其在系统中的运行模式是否是守护进程模式。也就是说只需设置为守护进程模式的应用程序才是服务程序。有些应用程序在安装时会自动设置为守护进程模式以实现开机程序自启动,并监听某些端口以供用户请求处理。例如通过包管理器默认安装方式安装sshd时(sshd属于openssh-server软件包的组件),会自动设置为守护进程模式以实现开机程序自启动,并监听默认的22端口以供用户通过ssh远程登录。

2)启动框架相关概念

启动框架(Boot framework)是计算机操作系统启动时用于管理和控制服务、程序和进程的一组工具和机制。简单的说:启动框架就是一组服务管理工具。它能够帮助用户在系统启动过程中加载和启动必要的服务和程序,并确保这些服务和程序能够以正确的顺序和方式运行。启动框架包含有一些管理工具用于实现:查看服务运行状态、查看服务自启动状态、启动服务、关闭服务、开启服务自启动(即所谓的设置开机自启动)、关闭服务自启动 等功能。

在 Linux 操作系统中,启动框架通常被称为引导框架(boot loader),其作用类似于 Windows 系统中的 BOOTMGR 或 NTLDR。启动框架通常会在操作系统内核初始化之后自动启动,并负责加载和管理其他服务和程序。它们还会根据预定义的运行级别或用户自定义的配置来控制有哪些服务、程序和进程需要在系统启动时自动运行。

常见的启动框架包括:SysVinit、Upstart、Systemd 和 OpenRC 等。

  1. SysVinit:SysVinit 是一种较早的 Linux 启动框架,它使用 /etc/init.d/ 目录下的脚本文件来控制系统服务的启动和停止。在 SysVinit 中,服务的运行状态与系统运行级别(runlevel)直接关联,用户可以使用 servicechkconfig 等命令来管理服务。
  2. Upstart:Upstart 是 Canonical 公司开发的一种 Linux 启动框架,其设计目标是提高启动速度并改善系统事件处理。Upstart 使用基于事件的模型代替了传统的 SysVinit 模型,并支持自动重启、故障恢复和进程监控等功能。
  3. Systemd:Systemd 是一种由 Lennart Poettering 开发的 Linux 启动框架,已经成为许多主流 Linux 发行版的默认启动框架。与 SysVinit 不同,Systemd 使用单一的 .service 文件来描述服务,并支持依赖关系、并行启动、延迟启动和日志记录等功能。用户可以使用 systemctl 命令来管理服务和控制系统状态。
  4. OpenRC:OpenRC 是 Gentoo Linux 发布版使用的一种 Linux 启动框架,也可以在其他 Linux 发行版中使用。OpenRC 使用 /etc/init.d/ 目录下的脚本文件来控制服务的启动和停止,并支持并行启动、依赖关系和自定义运行级别等功能。

提示:在 CentOS7.0 后 很多应用程序不再使用 SysVinit 而是使用 Systemd 来管理服务。

3)SysVinit 服务管理

简要概述

SysVinit 是一种较早的 Linux 启动框架,它使用 /etc/init.d/ 目录下的脚本文件来控制系统服务的启动和停止。在 SysVinit 中,服务的运行状态与系统运行级别(runlevel)直接关联,用户可以使用 servicechkconfig 等命令来管理服务。

Linux系统运行级别的概念

在SysVinit中有Linux系统运行级别的概念,Linux系统运行级别指的是系统启动时所处的运行状态,它决定了哪些服务、进程和资源会被启动或关闭。在 Linux 中,通常使用 SysV 初始化系统来管理运行级别。SysV 初始化系统其提供了 7 个运行级别,如下:

  • 运行级别 0:系统停机状态,即关机。
  • 运行级别 1:单用户模式,只有 root 用户可以登录终端,通常用于系统修复或恢复。
  • 运行级别 2:多用户模式,但不带 NFS 功能。
  • 运行级别 3:完全的多用户模式,通常是支持网络连接的服务器模式。
  • 运行级别 4:保留,未使用。
  • 运行级别 5:完全的多用户图形化模式,通常是桌面应用程序运行的模式。
  • 运行级别 6:系统重启,即重新启动操作系统。

在 Linux 中,Linux 系统的默认运行级别通常是 3 或 5,具体取决于 Linux 发行版和系统配置。如果用户需要修改系统启动时默认的运行级别,可对 /etc/inittab 文件中的 initdefault 参数进行配置。

1
2
3
4
#修改系统启动时默认的运行级别。配置initdefault参数
vi /etc/inittab
#查看当前系统的运行级别
runlevel
常用命令(servicechkconfigupdate-rc.d

提示:service 命令原本是用于管理 SysVinit 初始化管理的服务,但现在很多新系统改用 Systemd 初始化管理服务后,为了兼顾 service 的使用习惯,也同样支持用于管理 Systemd 启动的服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#查看SysVinit管理的服务
service --status-all
#或者:ls -l /etc/init.d

#启动服务
service 服务名 start
#关闭服务
service 服务名 stop
#重启服务
service 服务名 restart
#重载服务配置
service 服务名 reload
#查看服务运行状态
service 服务名 status

#Debian系列系统
#开启服务自启动(即所谓的设置开机自启动)
update-rc.d 服务名 defaults
#关闭服务自启动(-f: force)
update-rc.d -f 服务名 remove

#Redhat系列系统
#设置服务的自启动状态(可通过--level指定某运行级别下服务的自启动状态,不指定--level选项则默认作用于所有运行级别)
chkconfig --level <level> <service_name> <on|off> #如:chkconfig --level 3 httpd on
#开启服务自启动(即所谓的设置开机自启动)
chkconfig 服务名 on
#关闭服务自启动
chkconfig 服务名 off
  • service命令详解

service 命令是一种用于管理系统服务的工具。它可以启动、停止、重启以及查询系统服务的状态,作用于 /etc/init.d 目录下的服务脚本。是一种用于管理系统服务的工具。它可以启动、停止、重启以及查询系统服务的状态,作用于 /etc/init.d 目录下的服务脚本。

基本语法如下:

1
>service <service_name> <action>

其中,<service_name> 表示要操作的服务名称,例如 httpdsshd 等;<action> 表示要执行的操作,例如 startstoprestartstatus 等。

  • chkconfig命令详解

chkconfig 命令是 Linux 系统中用于管理 SysV 初始化脚本的命令之一。它可以让用户方便地设置某个服务在不同运行级别下的启动状态。

基本语法如下:

1
>chkconfig --level <level> <service_name> <on|off>

其中,--level 选项表示要设置的运行级别,例如 3 表示完全的多用户模式,不指定--level选项则默认作用于所有运行级别;<service_name> 表示要操作的服务名称;<on|off> 表示要执行的操作,即将服务设置为启动或停止状态。

实现原理:

根据/etc/init.d目录的服务脚本创建相应的符号链接(软链接),然后把这个符号链接放到表示不同运行级别的目录里,系统启动时 SysV 根据当前运行级别情况运行对应目录里的服务脚本。

常规Linux 发行版会把符号链接会被存放在/etc/rcN.d 目录里,RHEL 等一些特定的 Linux 发行版会把符号链接会被存放在/etc/rc.d/rcN.d 目录里。其中N表示运行级别。这些链接文件通常以 KS 字母开头,后面跟着服务名称和数字序列号,例如 K01httpdS99sshd。其中,K 表示停止服务,S 表示启动服务,数字序列号表示启动或停止的先后顺序。

例如:如果想要在运行级别 3 中启动 Apache 服务,可以将 /etc/init.d/httpd 复制到 /etc/rc3.d 目录,并将其重命名为 S80httpd,命令操作如:cp /etc/init.d/httpd /etc/rc3.d/S80httpd。这样,在系统进入运行级别 3 时,就会自动启动 Apache 服务。

💁‍♂ 注意:

restartreload的区别:restart = stop + start,而 reload = 重新读取配置文件

自定义服务

在 SysVinit 启动框架下自定义服务,可以按照以下步骤进行:

  1. 编写服务脚本(启动脚本)

    /etc/init.d 目录下创建一个服务脚本文件,文件名为自定义的服务名称。如:/etc/init.d/my_custom_service

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    #!/bin/bash
    # chkconfig: 345 99 10
    # description: My Custom Service

    case "$1" in
    start)
    /usr/bin/my_custom_service &
    ;;
    stop)
    pkill my_custom_service
    ;;
    restart)
    $0 stop
    sleep 5
    $0 start
    ;;
    *)
    echo "Usage: $0 {start|stop|restart}"
    exit 1
    ;;
    esac

    exit 0

    其中,chkconfig: 345 99 10 指定了运行级别和启动顺序。345 表示服务将在运行级别 3、4 和 5 中启动;99 表示启动顺序(数字越小越先启动);10 表示停止顺序(数字越大越后停止)。

  2. 启用服务

    使用 chkconfig 命令将服务添加到系统启动项,并将其设置为开机自动启动。

    1
    2
    3
    chmod +x /etc/init.d/my_custom_service
    chkconfig --add my_custom_service
    chkconfig my_custom_service on
  3. 启动服务

    使用 service 命令启动服务。

    1
    service my_custom_service start

4)Systemd 服务管理

简要概述

Systemd 是一种由 Lennart Poettering 开发的 Linux 启动框架,已经成为许多主流 Linux 发行版的默认启动框架。与 SysVinit 不同,Systemd 使用单一的 .service 文件来描述服务,并支持依赖关系、并行启动、延迟启动和日志记录等功能。用户可以使用 systemctl 命令来管理服务和控制系统状态。

常用命令(systemctl)

提示:systemctl 命令不可以用于管理 SysVinit 启动的服务。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#查看Systemd管理的服务(Systemd会从以下目录中加载Systemd单元文件,如果存在同名文件,Systemd将使用较高优先级路径里的单元文件配置)
ls /etc/systemd/system #优先级最高(包含用户自定义的单元文)
ls /run/systemd/system #比以上优先级低(包含运行时生成的单元文件)
ls /lib/systemd/system #比以上优先级低(包含Linux系统自带的单元文件和第三方服务安装的单元文件)
ls /usr/lib/systemd/system #比以上优先级低(默认和/lib/systemd/system文件内容一致)

#启动服务
systemctl start 服务名
#关闭服务
systemctl stop 服务名
#重启服务
systemctl restart 服务名
#查看服务运行状态
systemctl status 服务名

#查看所有服务自启动状态
systemctl list-unit-files #systemctl list-unit-files | grep 服务名
#开启服务自启动(即所谓的设置开机自启动)
systemctl enable 服务名
#关闭服务自启动
systemctl disable 服务名
#查询某个服务是否是自启动的
systemctl is-enabled 服务名

#查看服务日志
journalctl -u 服务名

💁‍♂ 说明:

systemctl命令自带有服务自启动管理功能,可直接使用该命令来维护服务的自启动状态。

💁‍♂ 关于/lib/systemd/system 目录和 /usr/lib/systemd/system 目录默认文件相同的说明:

在 Linux 操作系统中,/usr/lib 目录和 /lib 目录都是用于存储共享库文件的目录。事实上,/usr/lib 目录中的大部分内容都可以在 /lib 目录中找到相应的文件。这是因为,早期版本的 Linux 发行版将所有的用户空间程序和库文件都安装在 /usr 目录中,而 /lib 目录只包含内核和驱动程序所需的库文件。随着 Linux 发行版的不断发展和演变,为了提高兼容性和可移植性,一些 Linux 发行版开始将某些库文件安装在 /lib 目录中,以避免某些应用程序无法正常工作。但是,出于向后兼容的考虑,又不能将所有的库文件都直接移到 /lib 目录下。这就导致了 /usr/lib/lib 目录中的内容存在大量重复的情况。总之,在现代 Linux 系统中,/usr/lib 目录中的大部分内容都可以在 /lib 目录中找到相应的文件。这是由于历史原因和兼容性考虑所导致的,用户不需要过多关注这个问题,只需要根据需要使用相应的库文件即可。

自定义服务

在 Systemd 中管理自定义服务的步骤如下:

  1. 编写服务文件

    创建一个描述服务的配置文件,并将其保存到 /etc/systemd/system 目录中,文件名以 .service 结尾。如:my_custom_service.service

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    [Unit]
    Description=My Custom Service
    After=network.target

    [Service]
    ExecStart=/usr/bin/my_custom_service
    Restart=always

    [Install]
    WantedBy=multi-user.target

    Systemd 服务单元文件的一些常见配置选项及其详细说明:

    1. [Unit] 部分:
    • Description:描述该服务的文字说明。
    • Documentation:提供有关该服务的文档链接或路径。
    • RequiresWants:指定该服务所依赖的其他单元,要求它们在该服务之前启动。
    • After:指定该服务应该在哪些其他单元之后启动。
    1. [Service] 部分:
    • Type:指定服务的类型,如 simpleforkingoneshotdbus 等。
    • ExecStart:指定启动该服务时要执行的命令或脚本。
    • ExecStop:指定停止该服务时要执行的命令或脚本。
    • WorkingDirectory:指定服务的工作目录。
    • UserGroup:指定服务运行的用户和组。
    • Environment:设置服务运行时的环境变量。
    • Restart:指定服务在异常退出时的重启策略。
      • no:表示不进行重启,默认情况下,当服务停止或退出时不会自动重启。
      • on-failure:表示仅在服务发生非正常的退出(即退出状态不为零)时才重启。这是默认的重启策略。
      • always:表示无论服务退出的状态如何(无论是正常还是非正常),都进行重启。
      • on-abnormal:表示仅在服务发生异常退出时才重启,例如由于收到未捕获的信号导致服务终止。
      • on-success:表示仅在服务正常退出(即退出状态为零)时才重启。
      • on-watchdog:表示仅在由 Systemd 监控的 watchdog 定时器触发时才重启。
      • on-abort:表示仅在服务启动过程中遇到致命错误时才重启。
    • RestartSec:指定在重启服务之前等待的时间间隔。
    • ExecReload:指定重新加载服务时要执行的命令或脚本。
    1. [Install] 部分:
    • WantedBy:指定该服务应该在哪些目标(target)中启用。通常为 multi-user.target 或类似的目标。
  2. 重新加载 Systemd 配置

    使用 systemctl 命令重新加载 Systemd 配置,使之生效。

    1
    systemctl daemon-reload
  3. 启用开机自启动

    使用 systemctl 命令将服务添加到开机自启动项,并设置为开机自动启动。

    1
    systemctl enable my_custom_service.service
  4. 启动服务

    使用 systemctl 命令启动服务。

    1
    systemctl start my_custom_service.service

    至此,自定义服务已经成功地添加到 Linux 系统中,并且可以通过 systemctl 命令来管理它。

需要注意的是,在编写服务文件时,要遵循规范,确保服务能够正确地启动、停止和重启。在使用 Systemd 进行服务管理时,还可以使用其他一些命令来管理服务,例如 systemctl stopsystemctl restartsystemctl statusjournalctl 等。

6. 分配 swap 空间

简要概述

在安装 Linux 系统时在分区时可以分配 swap 空间(交换空间,即虚拟内存),而系统安装后(在运行中)如何创建或调整 swap 空间呢?

在装完 Linux 系统之后,分配 swap 空间有两种方式。

提示:可通过命令 free -h 查看当前系统的 swap 空间大小。

方式1:新建磁盘分区作为 swap 分区

1
2
3
4
5
6
7
8
9
10
11
12
#停止所有的 swap 分区
swapoff -a
# 用 fdisk 命令对某个磁盘进行分区,添加 swap 分区,新建分区,在 fdisk 中用 t 命令将新添的分区 id 改为 82(Linux swap 类型),最后用 w 将操作实际写入硬盘(没用 w 之前的操作是无效的)。如下:
fdisk /dev/sdb
#格式化 swap 分区,这里的 sdb2 要看加完后 p 命令显示的实际分区设备名
mkswap /dev/sdb2
#激活启用新的 swap 分区
swapon /dev/sdb2
#为了让系统启动时能自动启用这个交换分区,可以编辑 /etc/fstab 加入下面一行
/dev/sdb2 swap swap defaults 0 0
# 启用 /etc/fstab 里的所有 swap 分区(可选)
# swapon -a

停用 swap 分区,操作如下:

1
2
3
4
#停用指定 swap 分区
swapoff /dev/sdb2
#删除或注释 /etc/fstab 中之前添加的相关挂载 swap 分区的开机自启动内容
#/dev/sdb2 swap swap defaults 0 0

方式2:用虚拟磁盘分区作为 swap 分区(推荐)

1
2
3
4
5
6
7
8
9
10
11
#创建一个新的虚拟磁盘分区(即文件)
mkdir /swap
dd if=/dev/zero of=/swap/swapfile bs=1M count=1024 #大小可自己调整(文件大小 = bs * count)
#格式化为交换分区文件
mkswap /swap/swapfile #设置拟磁盘分区的文件系统
#设置文件权限(可选)
chmod 600 /swap/swapfile
#激活启用新的 swap 分区
swapon /swap/swapfile
#使系统开机时自启用,可以编辑 /etc/fstab 加入下面一行
/swap/swapfile swap swap defaults 0 0

提示:系统的 swap 空间总容量由一个或多个 swap 分区来共同组成,停掉某些 swap 分区,系统的 swap 空间总容量也会随着减少掉相应的大小。所以想要增加 swap 空间总容量,只需要创建激活 swap 分区即可,减少容量则关停并删除某些 swap 分区即可

停用 swap 分区,操作如下:

1
2
3
4
5
6
#停用指定 swap 分区
swapoff /swap/swapfile
#删除 swap 分区文件
rm /swap/swapfile
#删除或注释 /etc/fstab 中之前添加的相关挂载 swap 分区的开机自启动内容
#/swap/swapfile swap swap defaults 0 0

参考

九、网络管理

1. 查看网卡配置信息 ifconfig

ifconfig 可以查看当前的网卡配置信息(主要含网卡名称、IP 信息等)

1
2
3
4
5
# 查看网卡配置信息
ifconfig

# 查看网卡对应的 IP 地址
ifconfig | grep inet

提示:一台计算机中有可能会有一个 物理网卡多个虚拟网卡,在 Linux 中物理网卡的名字通常以 ensXX 表示

网卡是一个专门负责网络通讯的硬件设备。IP 地址是设置在网卡上的地址信息。每台联网的电脑上都有 P 地址,是保证电脑之间正常通讯的重要设置。

我们可以把 电脑 比作 电话网卡 相当于 SIM 卡IP 地址 相当于 电话号码

注意:每台电脑的 IP 地址不能相同,否则会出现 IP 地址冲突,并且没有办法正常通讯

127.0.0.1 被称为 本地回环/环回地址,一般用来测试本机网卡是否正常

2. 检测网络连通性 ping 和 telnet

ping 一般用于检测当前计算机到目标计算机之间的网络是否连通,time数值越大,速度越慢

1
2
3
4
5
6
7
8
9
10
11
12
## 测试 IP 连通性
# 检测到目标主机是否连接正常
ping IP地址
# ping 本机 IP
ping baidu.com
ping 127.0.0.1 #等同:ping localhost


## 测试端口连通性
#在 telnet 会话连通后,如果不自动退出,需输入 Ctrl+] 组合键,在出现的提示符下输入 quit,然后按 Enter 键即可退出。
telnet IP地址 端口
telnet baidu.com 443

ping 的工作原理与潜水艇的声纳相似,ping 这个命令就是取自 声纳的声音

网络管理员之间也常将 ping 用作动词 —— ping 一下计算机X,看他是否开着

原理:网络上的机器都有 唯一确定的 IP 地址,我们给目标 IP 地址发送一个数据包,对方就要返回一个数据包,根据返回的数据包以及时间,我们可以确定目标主机的存在

提示:在 Linux 中,想要终止一个终端程序的执行,绝大多数都可以使用 CTRL + C

3. 配置主机名

1
2
3
4
5
6
7
8
9
10
11
12
#查看主机名
hostname

##持久化修改主机名
#方式1(推荐):
hostnamectl set-hostname "主机名称"
#如:hostnamectl set-hostname "centos7-test"

#方式2:
echo "主机名称" > /etc/hostname
#如:echo "centos7-test" > /etc/hostname
reboot #注意,如果修改配置文件的方式设置主机名,则需要重启系统

4. 配置 hosts 映射

1
2
#编辑/etc/hosts然后配置ip和对应域名即可
vim /etc/hosts

5. 配置主机 IP

1)配置临时 IP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
##设置临时IP(ifconfig 命令)
#ifconfig 命令设置IP,会把替换掉原网络接口的IP
#<interface_name> 为网络接口名称(如:eth0 或 ens33 等,可通过执行 ip addr 命令查看)
#格式:ifconfig <interface_name> <IP>/<子网掩码> 或者 ifconfig <interface_name> <IP> netmask <子网掩码>
#示例:
# 首先,禁用网络接口(如果已经启用)
ifconfig ens33 down
# 配置IP地址和子网掩码
ifconfig ens33 192.168.60.100/24
# 启用网络接口
ifconfig ens33 up

#临时设置网关IP
#格式:ip route add default via <gateway_ip>
#或者:route add default gw <gateway_ip>(一些旧版的Linux系统仅支持route add default gw <gateway_ip>)
ip route add default via 192.168.60.2

#临时设置DNS服务器
#格式:echo "nameserver <dns-ip>" >> /etc/resolv.conf
echo "nameserver 8.8.8.8" >> /etc/resolv.conf

其他相关命令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
##添加临时IP(ip addr add 命令)
#ip addr add 命令用于添加IP(即如果之前网络接口已经存在默认IP,则该命令会在保留原IP的情况下添加一个新的IP,使得多个IP可用)
#<interface_name> 为网络接口名称(如:eth0 或 ens33 等,可通过执行 ip addr 命令查看)
#格式:ip addr add <IP>/<子网掩码> dev <interface_name>
#示例:
ip addr add 192.168.60.100/24 dev ens33

##移除临时IP(ip addr del 命令)
#<interface_name> 为网络接口名称(如:eth0 或 ens33 等,可通过执行 ip addr 命令查看)
#格式:ip addr del <IP>/<子网掩码> dev <interface_name>
#示例:
ip addr del 192.168.60.100/24 dev ens33


#还原IP(重启网络接口方式)
#<interface_name> 为网络接口名称(如:eth0 或 ens33 等,可通过执行 ip addr 命令查看)
ifconfig <interface_name> down
ifconfig <interface_name> up
#或
#ip link set <interface_name> down
#ip link set <interface_name> up

#还原IP(重启网络服务方式)
service network restart

2)配置静态 IP

说明:静态 IP 即重启系统或者网络后不会改变的 IP。

(一)环境准备

如果 Linux 系统设置自动配置网络 IP (即 DHCP),那么虚拟机系统的 IP 将会默认由网关动态随机分配,所以重启系统或者网络的情况,这个 IP 可能会发生改变。如果希望重启系统或者网络后 IP 固定不变的话,则需要手动对网卡配置固定的静态 IP。

(1)确定要配置静态 IP 的子网、子网掩码、网关 IP

要配置静态 IP 就要提前先确定静态 IP 的子网、子网掩码、网关 IP。这里以 VMware 的 Linux 虚拟机在 NAT 模式下配置静态 IP 为例进行讲解,操作如下:

  • 确定子网:

对于 NAT 模式,VMware 使用 VMnet8 这个宿主机虚拟网卡来管理 IP 的,其默认子网在安装 VMware 时初始化为一个默认值,通常为 192.168.x.0(如:192.168.60.0),不同设备该值可能不同,具体可以通过查看宿主机的 VMnet8 网卡配置来确定,或者在 VMware 的 “虚拟网络编辑器” 中查看,操作如下:

1548175001833

image-20240108131350157

提示:

  • 如对默认设置的子网不满意,则可以点击 “更改设置” 来进行修改,修改子网后,网关 IP 也会自动跟着改变。
  • 如果发现虚拟网络配置的子网段和宿主机的 VMnet8 网卡的配置不一致,需要点击 “更改设置” 以修改为同网段。
  • 确定子网掩码:

子网掩码默认都为 255.255.255.0

  • 确定网关 IP:

默认 VMnet8 的网关 IP 为子网的一个 IP,通常为 x.x.x.2(如:192.168.60.2

image-20220504030250858

(2)配置虚拟机的网络连接方式为" NAT 模式"。

image-20200423025556615

(3)进入 Linux 虚拟机终端,编辑 Linux 网卡配置文件,对于不同发行版 Linux 的网卡配置文件路径和名称可能不同,可通过ifconfig命令来查看网卡名称。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[root@localhost ~]# ifconfig
# ens33 即网卡名称
ens33: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.60.112 netmask 255.255.255.0 broadcast 192.168.60.255
inet6 fe80::20c:29ff:fe09:6067 prefixlen 64 scopeid 0x20<link>
ether 00:0c:29:09:60:67 txqueuelen 1000 (Ethernet)
RX packets 256 bytes 39985 (39.0 KiB)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 151 bytes 19628 (19.1 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0

然后编辑网卡配置文件

  • Red Hat 系列系统的配置文件路径为:/etc/sysconfig/network-scripts/ifcfg-<网络接口名称>(如:/etc/sysconfig/network-scripts/ifcfg-ens33
  • Debian 系统的配置文件路径为:/etc/network/interfaces
  • Ubuntu 系统的配置文件路径为:/etc/netplan/<xxx>-config.yaml(如:/etc/netplan/00-installer-config.yaml
(二)Red Hat / CentOS 系统配置静态 IP
1
2
vi /etc/sysconfig/network-scripts/ifcfg-<网络接口名称>
#如:vi /etc/sysconfig/network-scripts/ifcfg-ens33

修改如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
-BOOTPROTO="dhcp"
+BOOTPROTO="static"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="ens33"
UUID="4f676de2-5673-431b-b8fc-2dc4ad9accfc"
DEVICE="ens33"
-ONBOOT="no"
+ONBOOT="yes"
+IPADDR="192.168.60.100"
+GATEWAY="192.168.60.2"
+NETMASK="255.255.255.0"
+DNS1="223.5.5.5"
+DNS2="8.8.8.8"

💡 提示:网卡配置文件里的变量可能不同系统的也不同。但是以上修改的部分是必须的。

📚 主要变量说明:

  • HWADDR:表示mac地址
  • TYPE:网络类型
  • BOOTPROTO:表示为网卡配置静态还是动态IP地址(none:表示无须启动协议;bootp:表示使用BOOTP协议;dhcp :使用dhcp协议动态获取ip地址; static:表示手工设置静态IP地址)
  • ONBOOT:表示启动系统时是否激活网卡,yes为激活,no不激活(如果默认为no需要改成yes)
  • HWADDR:表示网卡的MAC地址
  • GATEWAY:表示该网关地址。填虚拟虚拟机网卡VMnet8对应的网关ip。
  • NETMASK:表示子网掩码。填填和VMnet8对于的子网掩码
  • IPADDR:表示网卡的静态IP地址。比如上面的网关是192.168.60.2并且子网掩码是255.255.255.0,那么表示固定ip的值需要是192.168.60.x(这个x是除了网关外3~254的任意数填,其中0表示网络,255一般用来做掩码,而1和2已经被VMnet8使用,所以0、1、2和255不用)
  • DNS1(可选):表示第一个DNS服务器的地址。值可以是任意能使用的dns ip地址(用于解析域名)。这里使用google通过的dns ip8.8.8.8即可。(注意:如果 Vmware 虚拟机使用“仅主机模式”的话,不要设置 DNS ,否则可能会出现 SSH 登录超时的问题。)
  • DNS2(可选):表示第二个DNS服务器的地址。

重启网络服务以生效

1
2
3
4
#重启网络服务
service network restart
#如果上面命令重启 ip 没变,可以尝试重启系统试试
reboot

执行后如果报如下错误:
Restarting network (via systemctl): Job for network.service failed because the control process exited with error code. See “systemctl status network.service” and “journalctl -xe” for details.

💁‍♂ 出现上面错误的大概率是mac地址和vmware配置的不一致。如下一定要一致:

image-20220504023438615

(三)Debian 系统配置静态 IP
1
vi /etc/network/interfaces

配置内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
#allow-hotplug ens33
#iface ens33 inet dhcp

#允许网卡接口热插拔
allow-hotplug ens33
#开机启动时自动激活网卡接口
auto ens33

#static表示使用固定IP,dhcp表述使用动态IP
#iface ens33 inet dhcp
iface ens33 inet static

#设置静态IP地址
address 192.168.60.201
#设置子网掩码
netmask 255.255.255.0
#设置网关
gateway 192.168.60.2
#设置DNS服务器(可选)
dns-nameservers 223.5.5.5 8.8.8.8

重启网络服务以生效

1
2
3
4
5
#重启网络服务
service networking restart

#如果上面命令重启 ip 没变,可以尝试重启系统试试
reboot
(四)Ubuntu 系统配置静态 IP
1
2
vi /etc/netplan/<xxx>-config.yaml
#如:vi /etc/netplan/00-installer-config.yaml

配置内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
network:
version: 2
renderer: networkd #指定后端采用systemd-networkd或者Network Manager,可不填写则默认使用systemd-workd
ethernets:
ens33: #配置的网卡的名称
dhcp4: no #关闭DHCP,如果需要打开DHCP则写yes
#dhcp6: no
addresses:
- 192.168.60.130/24 #配置的静态ip地址和掩码
#- 可配置 IPV6 地址
routes:
- to: default
via: 192.168.60.2 #网关地址
nameservers:
addresses: [223.5.5.5, 8.8.8.8] #DNS服务器地址,多个DNS服务器地址需要用英文逗号分隔开

重新加载配置以生效

1
netplan apply

参考:

(五)Rocky Linux 系统配置静态 IP

参考:

网卡配置文件修改法:

交互式配置法:

6. 配置 DNS 服务器

1)公共 DNS 服务器介绍

国内的常用 DNS 服务

国外常用 DNS 服务

  • Google Public DNS
    • IPv4:8.8.8.88.8.4.4
    • IPv6:2001:4860:4860::88882001:4860:4860::8844
  • Cloudflare DNS
    • IPv4:1.0.0.11.1.1.1
    • IPv6:2606:4700:4700::11112606:4700:4700::1001
  • OpenDNS
    • IPv4:208.67.222.222208.67.220.220
    • IPv6:2620:119:35::352620:119:53::53参考

最佳实践推荐:解析国内站点推荐使用阿里 DNS 和腾讯 DNSPod(注重稳定请用前者、注重准确请用后者);解析海外网站推荐主 DNS 1.0.0.1208.67.222.222,备 DNS 8.8.8.88.8.4.4

参考:

2)查看当前使用的 DNS 服务器

1
2
3
4
5
6
7
8
9
##查看当前使用的 DNS 服务器(通用命令)
cat /etc/resolv.conf

##查看当前使用的 DNS 服务器(系统使用 systemd-resolved 维护 DNS 的情况)
#在 Ubuntu 16.10 或更新的版本中,/etc/resolv.conf 文件通常由 systemd-resolved 服务动态生成和管理。因此,直接查看 /etc/resolv.conf 文件可能不会显示 DNS 服务器的配置,需要通过 resolvectl status 命令进行查看
resolvectl status

##查看当前使用的 DNS 服务器(系统使用 resolvconf 维护 DNS 的情况)
resolvconf -l

将看到一个或多个 nameserver 行,每行后面跟着 DNS 服务器的 IP 地址

3)Linux 系统配置 DNS 服务器

(1)临时配置系统 DNS 服务器

Linux 系统的 DNS 配置由 /etc/resolv.conf 配置文件的 DNS 配置内容决定的,临时情况只需要在该文件里配置一个或多个 nameserver 即可使用自定义的 DNS 服务器(没有 nameserver 则表示不使用 DNS 服务器),修改该文件后会立即生效(不需要重启网络等操作),配置如下:

1
2
3
4
5
6
7
#添加或修改 nameserver 行以指定 DNS 服务器的 IP 地址
#可配置一个或多个 nameserver 行,每行后面跟着 DNS 服务器的 IP 地址
vi /etc/resolv.conf
#配置内容如下:
search localdomain
nameserver 223.5.5.5
nameserver 8.8.8.8
(3)永久配置 DNS 服务器
方式 1、维护网络接口配置文件的 DNS 配置(推荐)

提示:在网络接口配置文件中,如果获取 IP 的方式为静态的,则需要手动配置 DNS 服务器,这些配置会自动更新到 /etc/resolv.conf 文件中。如果获取 IP 的方式为 DHCP,则可以不用手动设置 DNS 服务器,系统会自动使用 DHCP 分配的 DNS 服务器并更新到 /etc/resolv.conf 文件中,而在 DHCP 的情况下又手动自定义了 DNS 服务器,那么自定义的 DNS 服务器和 DHCP 分配的 DNS 服务器都会同时更新到 /etc/resolv.conf 文件中。

对于 Redhat 系列系统,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
#(1)编辑网络接口配置文件
vi /etc/sysconfig/network-scripts/ifcfg-<网络接口名称>
#如:vi /etc/sysconfig/network-scripts/ifcfg-ens33
#添加或修改如下 DNS 配置
DNS1="223.5.5.5"
DNS2="8.8.8.8"

#(2)重启网络服务以生效
service network restart


#(3)查看当前使用的 DNS 服务器(编辑网络接口的 DNS 配置会自动更新到 /etc/resolv.conf 文件中)
cat /etc/resolv.conf

对于 Debain 系统,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#(1)编辑网络接口配置文件
vi /etc/network/interfaces
#添加或修改如下 DNS 配置
dns-nameservers 223.5.5.5 8.8.8.8

#(2)安装 resolvconf 服务
#以上 dns-nameservers 配置在最小化安装的 Debian 系统中可能不会生效(即不会自动更新到 /etc/resolv.conf 中),如需使其生效,可如下操作:
#安装 resolvconf
apt install -y resolvconf
#启用 resolvconf 服务自启动并立即允许服务
systemctl enable --now resolvconf.service

#(3)重启网络服务以生效
service networking restart


#(4)查看当前使用的 DNS 服务器(编辑网络接口的 DNS 配置会自动更新到 /etc/resolv.conf 文件中)
cat /etc/resolv.conf

对于 Ubuntu 系列系统,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#(1)编辑网络接口配置文件
vi /etc/netplan/<xxx>-config.yaml
#如:vi /etc/netplan/00-installer-config.yaml
#添加或修改如下 DNS 配置(关注:nameservers)
network:
#其他配置
ethernets:
#其他配置
ens33: #配置的网卡的名称
#其他配置
nameservers:
addresses: [223.5.5.5, 8.8.8.8] #DNS服务器地址,多个DNS服务器地址需要用英文逗号分隔开


#(2)重新加载配置以生效
netplan apply


#(3)查看当前使用的 DNS 服务器(编辑网络接口的 DNS 配置会自动更新到 /etc/resolv.conf 文件中)
cat /etc/resolv.conf
方式 2、禁止其他网络配置工具自动更新 DNS

由于这种方式修改的内容较多,所以不推荐

手动修改 /etc/resolv.conf 配置文件默认只能临时生效,通常重启网络或重启系统后,自定义的配置内容将会被重置,这是因为该文件的配置内容会被系统的一些其他网络配置工具(如:dhclient-script、NetworkManager 服务等)所默认维护,例如:dhclient-script、systemd-resolved、NetworkManager 等默认都会获取 DHCP 服务器的 IP 并自动追加到 /etc/resolv.conf 里,如果网络接口配置文件中还定义了其他的 DNS 配置,那么这些 DNS 配置也会被追加到 /etc/resolv.conf 中。如果不希望 /etc/resolv.conf 文件所手动自定义的内容被其他网络配置工具所影响,通常只需如下操作:

对于 Redhat 系列系统,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#1、禁止 NetworkManager 服务自动更新 DNS
echo -e "[main]\ndns=none" > /etc/NetworkManager/conf.d/no-dns.conf
systemctl restart NetworkManager.service

#2、禁止网络接口自动更新 DNS
#在网络接口配置文件中添加:PEERDNS="no",其表示禁止网络接口自动更新 /etc/resolv.conf 文件中的 DNS 服务器,默认 PEERDNS 的值为 true
vi /etc/sysconfig/network-scripts/ifcfg-<网络接口名称> #如:vi /etc/sysconfig/network-scripts/ifcfg-ens33

#3、清空 /etc/resolv.conf 文件的配置内容
echo "" > /etc/resolv.conf

#4、重启网络服务以生效
systemctl restart network

#5、自定义 DNS 服务器,之后配置将会永久有效(不会被其他网络配置工具所重置)
cat > /etc/resolv.conf << EOF
search localdomain
nameserver 223.5.5.5
nameserver 8.8.8.8
EOF



##如需恢复 NetworkManager 和网络接口来维护 /etc/resolv.conf,则如下操作:
#1、允许 NetworkManager 服务自动更新 DNS
rm -f /etc/NetworkManager/conf.d/no-dns.conf
systemctl restart NetworkManager.service
#2、允许网络接口自动更新 DNS
#删除或注释掉 PEERDNS="no"相关的行
vi /etc/sysconfig/network-scripts/ifcfg-<网络接口名称> #如:vi /etc/sysconfig/network-scripts/ifcfg-ens33
#3、重启网络服务以生效
#重启网络后 /etc/resolv.conf 的内容将会自动被 NetworkManager 和网络接口重置
systemctl restart network

对于 Debain 系统,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#1、禁用并立即停止 resolvconf 服务
systemctl disable --now resolvconf.service
#2、重启网络服务以生效
service networking restart
#3、清空 /etc/resolv.conf 文件的配置内容
echo "" > /etc/resolv.conf
#4、自定义 DNS 服务器,之后配置将会永久有效(不会被其他网络配置工具所重置)
cat > /etc/resolv.conf << EOF
search localdomain
nameserver 223.5.5.5
nameserver 8.8.8.8
EOF


#如需恢复 resolvconf 来维护 /etc/resolv.conf,则如下操作:
systemctl enable --now resolvconf.service
#重启网络服务以生效
service networking restart

对于 Ubuntu 系统,操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#1、禁用并立即停止 systemd-resolved 服务
systemctl disable --now systemd-resolved.service
#2、清空 /etc/resolv.conf 文件的配置内容
echo "" > /etc/resolv.conf
#3、自定义 DNS 服务器,之后配置将会永久有效(不会被其他网络配置工具所重置)
cat > /etc/resolv.conf << EOF
search localdomain
nameserver 223.5.5.5
nameserver 8.8.8.8
EOF


#如需恢复 systemd-resolved 来维护 /etc/resolv.conf,则如下操作:
systemctl enable --now systemd-resolved.service

参考:https://cloud.tencent.com/developer/article/1710514

4)Windows 系统配置 DNS 服务器

具体操作可参考:https://developer.aliyun.com/article/872704

补充说明:大部分情况下是直接生效,如未生效可尝试下面的办法,可通过如下命令刷新 DNS

1
ipconfig /flushdns

7. DNS 域名解析查询

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#使用 nslookup 命令查询
#查询结果含如下内容:
#(1)查询到的 IP 解析结果
#(2)查询域名时使用的 DNS 服务器(默认为系统配置的 DNS 服务器),可在使用时指定 DNS 服务器,如:nslookup example.com 8.8.8.8
#该命令可适用于 Windows 系统
nslookup example.com


#使用 dig 命令查询
#查询结果含如下内容:
#(1)查询到的 IP 解析结果
#(2)查询域名时使用的 DNS 服务器(默认为系统配置的 DNS 服务器),可在使用时指定 DNS 服务器,如:dig example.com @8.8.8.8
#(3)域名的 DNS 记录类型
dig example.com

8. 配置防火墙

1)简要概述

Linux 中常见的防火墙软件有 IPtables、UFW、FirewallD,通过这些工具可以对网络流量进行管理和控制,保障系统的安全性和稳定性。

注意:IPtables、UFW、FirewallD 这三种防火墙软件并不是独立的,而是存在联系和依赖关系。FirewallD 和 UFW 都是基于 IPtables 的前端工具,可以帮助用户更方便地配置和管理 iptables 规则。同时,IPtables 仍然是 Linux 系统中默认的防火墙软件之一,为其他防火墙软件提供了底层支持和功能。用户可以根据实际需求和环境选择合适的防火墙软件,并进行适当的配置和管理,以确保系统的安全性和高可用性。

2)IPtables 防火墙

IPtables 是 Linux 发行版中内置的基于 Netfilter 内核模块的防火墙软件,可用于控制和过滤网络流量。

在 iptables 中,有四个主要的表(table)和五个预定义的链(chain),分别是:

  1. filter 表:这是默认情况下使用的表,用于进行最常见的防火墙操作,例如过滤数据包、禁止或允许特定端口或 IP 地址等。它包含了三个主要的链:INPUT、OUTPUT 和 FORWARD 链。
  2. nat 表:这个表用于进行网络地址转换(NAT)操作,例如将私有 IP 地址映射到公共 IP 地址、修改源或目标 IP 地址等。它包含了三个主要的链:PREROUTING、POSTROUTING 和 OUTPUT 链。
  3. mangle 表:这个表用于修改数据包的头部信息,例如修改 TTL 值、标记数据包、更改 QoS 信息等。它包含了五个主要的链:PREROUTING、OUTPUT、INPUT、FORWARD 和 POSTROUTING 链。
  4. raw 表:这个表用于处理数据包之前的连接追踪(connection tracking)操作,例如禁止或允许特定协议、配置 ICMP 参数等。它包含了两个主要的链:PREROUTING 和 OUTPUT 链。

其中,五个预定义的链是:

  1. INPUT 链:这个链用于对传入到本机的入站数据包进行处理。
  2. OUTPUT 链:这个链用于对本机发起的出站数据包进行处理。
  3. FORWARD 链:这个链用于对通过本机进行转发的数据包进行处理。
  4. PREROUTING 链:这个链用于对通过网络接口的入站数据包进行处理。
  5. POSTROUTING 链:这个链用于对通过网络接口的出站数据包进行处理。

提示:Debain 等系统以及一些较旧版本的 Linux 发行版系统(例如:CentOS 6、Red Hat Enterprise Linux (RHEL) 6、Ubuntu 14.04 LTS 等)默认只安装有 iptables 防火墙软件,而未安装 UFW、FirewallD 等。如果系统中安装有这些上层的防火墙软件,但又希望只使用 iptables 来管理防火墙,则一定要卸载掉这些上层的防火墙软件。

(1)语法格式
1
iptables [-t 表名] 命令选项 [链名] [参数选项] [-j 动作]
  • [-t 表名]:可选参数,用于指定要操作的表名称。表定义了特定类型的规则集合。常见的表有filternatmangle。如果不指定表名,则默认为filter表。

  • 命令选项:指定要执行的操作命令。通常单字母命令选项为大写字母表示,常见的命令包括:

  • -A--append):在指定链的末尾添加一条新规则。(如 :-A <chain>

  • -D--delete):删除指定链中的一条规则。

  • -I--insert):在指定链的开头或指定位置插入一条新规则。(如:-I <chain> [num]num 表示链的行号(编号)位置,如果不指定则为链的开头)

  • -R--replace):替换指定链中的一条规则。

  • -L--list):列出指定链或表中的规则。

  • -F--flush):清除指定链中的所有规则。

  • -Z--zero):将指定链中的数据包和字节计数器归零。

  • [链名]:可选参数,用于指定要操作的链名称。链是规则的集合,它们决定了数据包的流向和处理方式。根据具体的表和命令,可能需要指定链名。

  • [参数选项]:用于指定规则的匹配条件和其他参数。通常单字母参数选项为小写字母表示,常见的参数选项包括:

  • [!] -s:指定匹配数据包的源地址或地址范围。表示方式:单个 IP 地址(如:-s 192.168.0.1)、CIDR 表示法(-s 192.168.0.0/24)、主机名(如:-s host1)、网络接口(如:-s eth0

  • [!] -d:指定匹配数据包的目标地址或地址范围。地址表示方式类比 -s

  • [!] -p:指定要匹配的协议类型,如:tcpudpicmpall(默认值,表示匹配所有协议)等。

  • [!] -i--in-interface):指定数据包进入防火墙的网络接口,用于匹配数据包的输入接口。

  • [!] -o--out-interface):指定数据包离开防火墙的网络接口,用于匹配数据包的输出接口。

  • [!] --sport:指定要匹配的单个源端口号。表示方式:单个端口(如:--sport 80

  • [!] --dport:指定要匹配的单个目标端口号。表示方式类比 --sport

  • [!] --sports:指定要匹配的多个源端口号。表示方式:单个端口(如:--sports 80)、逗号分隔的多个端口列表(如:--sports 80,443)、端口范围(如:--sports 8000:9000 ,表示匹配端口在 8000 到 9000 范围内的)

  • [!] --dports:指定要匹配的多个目标端口号。表示方式类比 --sports

  • [!] -m state --state 连接状态:匹配连接状态。NEW(新建的连接)、ESTABLISHED(已建立的连接)、RELATED(已关联连接,即已建立的连接)、INVALID(无效的连接)

说明:!(取反操作符)用于对匹配条件进行取反操作。它可以在规则中用于否定某个条件,从而选择与该条件不匹配的数据包。

  • -j 动作:用于指定规则匹配后要执行的动作。动作可以是接受、丢弃、拒绝、转发等。常见的动作包括:

  • ACCEPT:接受(允许)放行数据包,允许数据包通过防火墙。

  • DROP:丢弃(拒绝)数据包,直接丢弃匹配到的数据包,不给予任何响应。

  • REJECT:拒绝(拒绝访问)数据包,发送一个拒绝的响应给源主机,通知其访问被拒绝。

  • LOG:记录数据包信息,将匹配到的数据包的相关信息记录到系统日志中,以便后续分析。

  • DNAT:目标网络地址转换,用于目标地址的修改,通常与网络地址转换(NAT)一起使用。

  • SNAT:源网络地址转换,用于源地址的修改,通常与网络地址转换(NAT)一起使用。

  • MASQUERADE:网络地址转换(NAT)的一种特殊形式,将内部网络的数据包源地址修改为防火墙的外部接口地址。

  • REDIRECT:重定向数据包,将匹配到的数据包重定向到指定的目标地址和端口。

  • MARK:标记数据包,可以在匹配到的数据包上设置一个特定的标记,以供后续处理使用。

(2)添加规则
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#示例1:放行指定端口
# -t filter可省略
# 添加 “目标端口为80的TCP数据包允许传入” 的规则
iptables -t filter -A INPUT -p tcp --dport 80 -j ACCEPT

#示例2:拒绝某IP访问
#添加 “拒绝并丢弃源IP为192.168.100.10的传入数据包” 的规则
iptables -A INPUT -s 192.168.100.10 -j DROP


#设置常规安全的防火墙默认规则(即允许所有输出流量,但阻止所有输入和转发流量,另外允许ssh默认22端口的输入流量)
#iptables默认情况下没有设置任何规则,以确保网络安全推荐设置默认规则,然后再根据需要添加其他规则
iptables -t filter -A INPUT -p tcp --dport 22 -j ACCEPT
iptables --policy INPUT DROP
iptables --policy FORWARD DROP
iptables --policy OUTPUT ACCEPT
(3)删除规则
1
2
3
##示例1:删除放行指定端口规则
#删除 “目标端口为80的TCP数据包允许传入” 的规则
iptables -t filter -D INPUT -p tcp --dport 80 -j ACCEPT

该命令会删除指定端口的 iptables 规则。其中 -D 表示从链中删除规则。

(4)修改规则
1
2
#示例1:修改指定端口规则
iptables -t filter -R INPUT <num> -p tcp --dport <port> -j DROP

该命令会用新规则替换指定编号的旧规则,并拒绝传入 TCP 流量到指定端口。其中 -R 表示替换指定规则编号的规则。

(5)查看防火墙规则
1
2
3
4
5
6
7
8
9
#列出默认的filter表中所有链的所有规则
iptables -L
iptables -nvL
iptables -nvL --line-numbers

#列出filter表中INPUT链的所有规则(通常用于查看流量进入服务器时的端口放行规则和IP放行规则)
iptables -t filter -L INPUT -nv
#列出nat表中POSTROUTING链的所有规则(通常用于查看NAT地址转换规则)
iptables -t nat -L POSTROUTING -nv

参数说明:

  • -n:禁止将 IP 地址和端口号解析为主机名和服务名称。默认情况下,iptables会尝试解析 IP 地址和端口号为可读的主机名和服务名称,但使用-n参数可以避免此解析过程,以提高显示速度与可读性。
  • -L:列出规则。
  • [chain]:指定要操作的链名称(可选,默认为 filter 链)
  • --line-numbers:在每个规则前面显示规则的行号(编号)。
  • -v:以详细模式显示。该参数会在输出结果中显示规则的数据包和字节数统计信息。

该命令可以列出当前 iptables 的所有规则,包括链(chain)、策略(policy)和规则(rule)等信息。

(6)重置 iptables 规则
1
2
3
4
5
6
7
8
9
10
11
iptables --policy INPUT ACCEPT # 将输入链设置为默认接受所有数据包
iptables --policy FORWARD DROP # 将转发链设置为默认拒绝所有数据包
iptables --policy OUTPUT ACCEPT # 将输出链设置为默认接受所有数据包
iptables -F # 清除所有防火墙规则
iptables -X # 删除所有用户定义的链
iptables -Z # 清除所有计数器和数据包计数器

#注意,以上将会重置所有iptables规则,如果系统安装有Docker,则Docker相关的iptables规则也会被清空,为了保留Docker相关的iptables规则,可以通过重启Docker服务来自动添加回Docker相关的iptables规则,如下:
systemctl restart docker
#查看是否包含Docker相关的iptables规则
iptables -nvL
(7)防火墙规则持久化

默认通过 iptables 命令操作防火墙规则会立刻生效,但这些iptables规则还在本次系统运行时有效,一旦系统重启,iptables规则将会重置为默认设置,为了使iptables规则在系统重新启动后仍然有效,用户需要将规则保存到某个文件中,并在启动时加载这些规则。操作如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#导出当前的iptables规则并保存(可选择保存为任何文件路径)
mkdir -p /etc/sysconfig
iptables-save > /etc/sysconfig/iptables

#系统重启后,需要手动执行如下命令以重新导入配置文件中的iptables规则(导入后,规则会立刻生效)
iptables-restore < /etc/sysconfig/iptables


#如果不希望每次重启都手动导入,则可以将导入命令配置到系统启动加载配置文件中(使其能够开机自启动并自动导入 iptables 规则),如下:
#提示:/etc/network/if-pre-up.d目录下的脚本将会在系统重启过程网络接口启动之前自动执行。(重启网络服务也会自动执行)
cat > /etc/network/if-pre-up.d/iptablesload << EOF
#!/bin/bash
iptables-restore < /etc/sysconfig/iptables
EOF

#赋予执行权限
chmod +x /etc/network/if-pre-up.d/iptablesload

#重启测试
reboot

以上是手动维护配置文件和 iptables 持久化规则文件,操作比较麻烦,由此可以使用一些通用的工具简化实现,如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
##对于Debian/Ubuntu类系统,可以安装 iptables-persistent 工具包,使其以守护进程的方式来运行,这样系统重启后可以自动将保存的内容加载到 iptables 中,如下:
apt install -y iptables-persistent
#保存规则
service iptables-persistent save
#重启测试
reboot

##对于RHEL/CentOS类系统,可以安装 iptables-service 工具包,使其以守护进程的方式来运行,这样系统重启后可以自动将保存的内容加载到 iptables 中,如下:
#在 centos6 中默认有该工具包了,但在 centos7 中已经不能再使用类似 service iptables start 这样的命令了,所以 service iptables save 也无法执行,同时,在 centos7中,使用 firewall 替代了原来的 iptables service,不过不用担心,我们只要通过 yum 源安装 iptables与iptables-services 即可(iptables 一般会被默认安装,但是iptables-services 在 centos7 中一般不会被默认安装),在centos7 中安装完 iptables-services 后,即可像 centos6 中一样,通过 service iptables save 命令保存规则了,规则同样保存在 /etc/sysconfig/iptables 文件中
#配置好yum源以后安装iptables-service
yum install -y iptables-services
#停止firewalld
systemctl stop firewalld
#禁止firewalld自动启动
systemctl disable firewalld
#启动iptables
systemctl start iptables
#将iptables设置为开机自动启动,以后即可通过iptables-service控制iptables服务
systemctl enable iptables
#保存规则
service iptables save
#重启测试
reboot

参考:

(8)使用 IPtables 实现 TCP/UDP 端口转发

参考:

(9)参考

3)UFW 防火墙

UFW 是 Debian 系列 Linux 系统中 IPtables 防火墙的前端工具。旨在简化 iptables 的配置。

如果系统默认没有安装 UFW,则可执行命令安装:apt install ufw

(1)查看 ufw 服务状态
1
systemctl status ufw
(2)查看 ufw 的状态
1
2
#该命令可以看到ufw的状态(inactive是关闭,active是开启),ufw开启时还会列出当前配置的策略。
ufw status

注意:新安装 Ubuntu 系统,UFW 防火墙默认是不开启的。

(3)开启、重启、关闭、ufw 服务
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 启用服务(开机启动)
ufw enable
# 开启服务
systemctl start ufw

# 重启服务
systemctl restart ufw
# 重新加载UFW的配置文件(即 /etc/ufw/*.rules)
ufw reload


# 禁用服务(开机禁用)
ufw disable
# 关闭服务
systemctl stop ufw
(4)查看防火墙规则
1
ufw status
(5)防火墙端口规则维护
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
## 放行访问规则
#放行指定端口号访问(如果不带有TCP或者UDP,则默认两种都可以)
ufw allow 端口号
ufw allow 端口号/tcp
ufw allow 端口号/udp
#允许2200到2222端口的TCP流量允许访问
ufw allow 2200:2222/tcp
#设置特定的IP允许访问
ufw allow from xx.xx.xx.xx
#指定特定IP连接到特定端口允许访问
ufw allow from xx.xx.xx.xx to any poart 端口号
#设置特定的子网xx.xx.xx网段ip允许访问
ufw allow from xx.xx.xx.0/24

## 阻止访问规则
#阻止指定端口号访问(如果不带有TCP或者UDP,则默认两种都可以),注意如果之前有该端口的allow规则,那么只是改规则为deny,而不会删除规则
ufw deny 端口号
ufw deny 端口号/tcp
ufw deny 端口号/udp
#阻止2200到2222端口的tcp
ufw deny 2200:2222/tcp
#阻止特定IP访问
ufw deny from xx.xx.xx.xx
#阻止特定IP通过端口
ufw deny from xx.xx.xx.xx to any poart 端口号
#阻止特定子网xx.xx.xx网段ip允许访问
ufw deny from xx.xx.xx.0/24
#禁止外部访问smtp服务,#以服务名代表端口,可以使用less /etc/services列出所有服务信息, 其中包括该服务使用了哪个端口和哪种协议
ufw deny smtp
#删除上面建立的某条规则,或者ufw delete allow 80/tcp,如果出现无法删除,可以用序号:ufw status numbered,然后通过序号删除ufw delete 1
ufw delete allow smtp
#要拒绝所有的TCP流量从10.0.0.0/8 到192.168.0.1地址的22端口
ufw deny proto tcp from 10.0.0.0/8 to 192.168.0.1 port 22


## 配置出入(默认的规则都是进来的,我们可以通过in和out配置)
ufw allow in 2222 #允许2222端口的流量进来
ufw denty in 2222 #阻止2222端口的流量进来
ufw allow out 2222 #允许2222端口的流量出去
ufw denty out 2222 #阻止2222端口的流量出去

## 删除规则(两种方式)
#方式1:通过在规则前面加上delete删除规则
#删除放行的某端口规则
ufw delete allow 端口号
#方式2:通过查看规则序列号来删除
#查看规则序列号
ufw status numbered
#删除第3条规则
ufw delete 3


## 重置规则(恢复初始规则配置)
ufw reset

💁‍♂ 说明:

  • 一旦启用 UFW 之后,默认情况防火墙将不允许所有入栈连接访问,包括 SSH 连接,所以在开启防火墙之后,建议将 SSH 的监听端口设置为允许访问,操作如:ufw allow ssh (等价于:ufw allow 22
  • 在 UFW 中的所有修改都会立刻生效,不需要重新加载配置以来生效。

📖 参考:

4)FirewallD 防火墙

FirewallD 是 Red Hat 系列 Linux 系统中 IPtables 防火墙的前端工具。旨在简化 iptables 的配置。

(1)查看 firewall 服务状态
1
systemctl status firewalld
(2)查看 firewall 的状态
1
firewall-cmd --state
(3)开启、重启、关闭、firewalld.service 服务
1
2
3
4
5
6
7
8
9
10
11
12
# 开启服务
systemctl start firewalld
# 开机自启动服务
systemctl enable firewalld

# 重启
systemctl restart firewalld

# 关闭
systemctl stop firewalld
# 禁止开机自启动服务
systemctl disable firewalld
(4)查看防火墙规则
1
firewall-cmd --list-all
(5)防火墙端口规则维护
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#查询端口是否放行
firewall-cmd --query-port=8080/tcp
#放行80端口
firewall-cmd --permanent --add-port=80/tcp
#删除放行的80规则
firewall-cmd --permanent --remove-port=80/tcp

#放行端口区间
firewall-cmd --zone=public --add-port=4400-4600/tcp --permanent
firewall-cmd --zone=public --add-port=4400-4600/udp --permanent

#删除放行的端口区间规则
firewall-cmd --zone=public --remove-port=4400-4600/tcp --permanent
firewall-cmd --zone=public --remove-port=4400-4600/udp --permanent

#重新加载配置以使修改生效
firewall-cmd --reload

参数解释:

  • --permanent:表示设置为持久
  • --add-port:标识添加的端口

提示:FirewallD 没有类似 ufw reset 重置规则的命令,如需恢复初始规则配置只能手动维护。

9. 查看系统程序对应网络信息 netstat

般用于检验本机各端口的网络连接情况

1
2
3
4
5
6
7
8
#安装net-tools(包含ifconfig、netstat等网络命令的工具包)
yum install -y net-tools
apt install -y net-tools

netstat #命令用于显示各种网络相关信息,如网络连接, 路由表, 接口状态等等
netstat -lt #列出所有处于监听状态的tcp端口
netstat -tunlp #查看所有的监听端口(包括tcp和udp)信息, 同时含 PID 和进程名称
netstat -tunlp|grep 端口号 #用于查看指定监听端口号的进程情况
  • -a:显示所有连接和监听端口
  • -t:仅显示 TCP 连接
  • -u:仅显示 UDP 连接
  • -n:以数字形式显示 IP 地址和端口号,而不进行反向域名解析
  • -l:仅显示监听状态的连接
  • -p:显示建立相关连接的进程 ID

10. 网络测试工具 nc

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
##安装nc
yum install -y nc # CentOS/RedHat
apt install -y netcat # Ubuntu
apt install -y netcat-openbsd # Debian

##检查服务器端口是否通
nc -zv ip 端口
#如下:
$ root@ubuntu18:~# nc -zv 192.168.30.100 80
Connection to 192.168.30.100 80 port [tcp/http] succeeded!

##启动一个tcp端口(默认仅支持 IPv4,可添加 -4 -6 来同时支持 IPv4 和 IPv6)
nc -l -p 端口
#如下:
$ nc -l -p 8989 #服务端开启一个8989端口tcp进程
$ telnet 192.168.60.149 8989 #客户端通过telnet连接测试端口

##扫描端口(扫描指定ip某范围下启动的端口)
nc -v -w 1 ip -z 扫描起始的端口-扫描终止的端口
#如下:
$ nc -v -w 1 example.com -z 80-443
Connection to example.com 80 port [tcp/http] succeeded!
nc: connect to example.com port 81 (tcp) timed out: Operation now in progress
Connection to example.com 82 port [tcp/*] succeeded!
nc: connect to example.com port 83 (tcp) timed out: Operation now in progress
nc: connect to example.com port 84 (tcp) timed out: Operation now in progress

##验证UDP端口连通性
nc -l -u 8989 #服务端开启一个82端口udp进程
nc -uvz example.com 8989 #客户端连接服务端验证udp端口是否可用
#echo "hello" | nc -u -w1 example.com 8989 #客户端连接服务端udp端口并发生消息报文

11. 路由追踪 traceroute

现实世界中的网络是由无数的计算机和路由器组成的一张的大网,应用的数据包在发送到服务器之前都要经过层层的路由转发。而Traceroute是一种常规的网络分析工具,用来定位到目标主机之间的所有路由器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#-U 使用UDP协议(默认)发送数据包测试路由追踪(因为大部分的应用服务器都不提供UDP服务(或者被防火墙挡掉),所以会拿不到服务器的任何返回,所以不建议使用UDP测试)
#-T 使用TCP协议的SYN发送数据包测试路由追踪
#-I 使用icmp协议发送数据包测试路由追踪(ICMP即Internet控制报文协议,用于在IP主机、路由器之间传递控制消息的一种网络层协议,ICMP是IP协议的一部分,因此,ICMP协议的报文包含在IP数据报的数据部分。ICMP不像TCP或UDP有端口,只要服务器不禁止icmp消息,都是可以拿到路由应答的)
#-p 指定UDP端口。缺省值为 33434。如果 UDP 端口不可用,那么该选项可以用于选择一个未曾使用的端口范围。
#-m 指定最大ttl,默认30,即最大跳数
traceroute [参数] ip

# 测试(向baidu.com发送icmp数据包并追踪路由)
$ traceroute -I -m 100 baidu.com
traceroute to baidu.com (110.242.68.66), 30 hops max, 60 byte packets
1 _gateway (192.168.60.2) 0.075 ms 0.040 ms 0.037 ms
2 * * *
3 * * *
4 * * *
5 * * *
6 * * *
7 * * *
8 * * *
9 * * *
10 * * *
11 * * *
12 * * *
13 * * *
14 * * *
15 * * * #***的路由表示该路由服务屏蔽了ICMP消息
16 110.242.68.66 (110.242.68.66) 42.452 ms 42.450 ms 42.423 ms #共经历16跳后到达服务器

Windows系统中也有路由追踪工具,那就是tracerttracert采用的是icmp协议实现的,故不需要指定消息的协议。

1
2
#-h 指定最大ttl,默认30,即最大跳数
tracert ip

参考:

十、远程操作

1. 远程操作网络基础

域名:由一串“”用点分隔“”的名字组成,例如:www.baidu.com;是IP 地址的别名,方便用户记忆。

IP地址:IP 地址是网络中计算机的唯一网络标识。

端口号:是某台计算机上运行的应用程序的唯一网络标识。常见服务端口号列表:

序号服务端口号
01SSH 服务器22
02Web 服务器80
03HTTPS443
04FTP 服务器21

windows系统可以打开cmd输入以下命令检测网络互连的其他主机的端口号是否放行。

1
telnet ip 端口

提示:有关 端口号的详细内容,待续补充······

ssh协议: SSH是目前较可靠,专为远程登录会话和其他网络服务提供安全性的协议。特点:利用SSH协议可以有效防止远程管理过程中的信息泄露;通过SSH 协议可以对所有传输的数据进行加密,也能够防止 DNS 欺骗和 IP 欺骗;此外它还具有一个优点,就是是传输的数据可以是经过压缩的,所以可以加快传输的速度。

001_SSH示意图

要搭建ssh环境,需要分别安装服务端和客户端程序。SSH服务端是安装在服务器中提供ssh协议远程操控的服务软件。只有ssh服务端运行了才能通过ssh客户端连接服务器。

2. 远程登录

2.1 ssh服务端安装和配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
##切换到root用户
sudo -i

##安装ssh服务(如没有安装)
#Debian系列系统安装ssh服务
apt install openssh-server
#Redhat系列系统安装ssh服务
yum install openssh openssh-clients openssh-server -y

#编辑 sshd_config 配置文件
#将 PermitRootLogin 的值设置为 yes,表示允许 root 用户登录。
#将 PasswordAuthentication 的值设置为 yes,表示允许使用密码认证,如果为 no,则表示不允许使用密码认证,只能使用公钥认证。
#注意:如果在 sshd_config 配置文件中有导入其他配置文件,则需要注意导入的配置文件是否会覆盖配置内容,例如:Ubuntu22.04 中就会导入 /etc/ssh/sshd_config.d/50-cloud-init.conf 配置内容
vi /etc/ssh/sshd_config

##sshd服务管理命令
#systemctl start|stop|restart|enable|status <service>

#Redhat系列系统启动sshd服务,并设置开机自启动
systemctl start sshd #启动服务(通常安装后默认都已启动)
#或:service sshd start
systemctl enable sshd #开机自启动服务
#或:chkconfig --level 3 sshd on
systemctl restart sshd #重启服务(可选,如修改sshd_config配置,则需要重启服务)
#或:service sshd restart

#Redhat系列系统启动ssh服务,并设置开机自启动
systemctl start ssh #启动服务
#或:service ssh start
systemctl enable ssh #开机自启动服务
#或:chkconfig --level 3 ssh on
systemctl restart ssh #重启服务(可选,如修改sshd_config配置,则需要重启服务)
#或:service ssh restart


##配置root用户密码认证(只需设置root用户密码即可)
passwd root
##配置root用户公钥认证(只需将客户端的ssh公钥内容导入到root用户的ssh配置即可)
#清除root用户的默认ssh配置(防止一些默认脚本影响使用,如authorized_keys文件原本就没有脚本内容则无需操作)
echo "" > /root/.ssh/authorized_keys
#将客户端的ssh公钥内容导入到root用户的ssh配置中(客户端可通过 cat ~/.ssh/id_rsa.pub 命令获取ssh公钥内容)
echo "ssh公钥内容" >> /root/.ssh/authorized_keys

2.2 ssh客户端安装和使用

SSH 客户端是一种使用SSH协议连接到远程计算机的软件程序,通过SSH 客户端我们可以连接到运行了 SSH 服务器的远程机器上。

1
2
#默认系统已经安装,如果没有可通过命令来安装
apt install openssh-client

(1) Linux下SSH 客户端的简单使用

1
2
3
4
5
##ssh远程连接服务器
#user是在远程机器上的用户名,如果不指定的话默认为当前用户
#remote是远程机器的地址,可以是IP或者域名
#port是SSH Serve监听的端口,如果不指定,就为默认值22
ssh [-p port] user@remote

注意:如果在 Windows 系统中,可以安装 PuTTY 或者 XShell 客户端软件即可。

提示:使用 exit 退出当前用户的登录

(2) Windows 下 SSH 客户端的安装

1)ssh免密码登录

实现方式:使用公钥认证进行登录。

原理:使用非对称加密原理进行登录认证。首先由ssh客户端生成密钥对,然后用户将公钥添加到服务端的某认证配置文件里。当用户登陆时,会通过私钥对请求数据进行签名,并将已经签名的数据发送给ssh服务端,ssh服务端会去认证配置文件拿到公钥并进行验签,如果验签成功则允许登入,否则拒绝。由于私钥只有保存在用户自己的客户端中,因此入侵者就算得到用户公钥,也不能登陆到服务器。

非对称加密算法:

使用 公钥 加密的数据,只能使用 私钥 解密

使用 私钥 加密的数据,只能使用 公钥 解密

实现步骤

(1)SSH客户端生成密钥对

1
2
3
4
5
# 生成密钥对,一路回车即可。会在~/.ssh下生成一个私钥文件(id_rsa)和一个公钥文件(id_rsa.pub)
ssh-keygen

# 默认 ssh 秘钥标识为 “root@主机名”,如果希望自定义标识可如下实现:
ssh-keygen -t rsa -C "[email protected]"

1541837505008

终端会提示一些问题:

  • 第一个问题是设置私钥和公钥的文件名,如果不设置默认是id_rsaid_rsa.pub
  • 第二个问题是要不要对私钥设置口令(passphrase),如果担心私钥的安全则可以设置。

关于多个客户端使用同一个 ssh key 的实现方式:

每个客户端连接服务器都需要配置该客户端自己的 ssh key 到服务器中。通常情况下,不同的客户端会使用不同的 ssh key,这样虽然更能保护私钥的安全,但也会导致多密码管理麻烦。如果用户能确保多个客户端都是自己的,那么可以让这些客户端使用同一个 ssh key,这样就只需要设置一个 ssh key 到服务器,多个客户端就能免密连接服务器了。虽然可以直接复制 ssh key 到其他的客户端中,但在 Linux 客户端中使用时可能会提示失败:WARNING: UNPROTECTED PRIVATE KEY FILE!,解决办法是:对复制的文件重新设置操作权限,命令如下:

1
2
chmod 600 ~/.ssh/id_rsa
chmod 644 ~/.ssh/id_rsa.pub

(2)上传公钥到服务器

方式1:直接copy客户端的~/.ssh/id_rsa.pub内容直接追加到服务端的~/.ssh/authorized_keys里。

方式2:SSH客户端执行以下命令上传 到服务端:

1
2
#执行完命令即可上传客户端公钥到指定的服务器的~/.ssh/authorized_keys里(其实就是追加了id_rsa.pub的内容)
ssh-copy-id -p port user@remote

执行完以上操作后,远程服务器即可认证客户端,客户端也有了ssh免密登录的权限。

示意图:

003_SSH 免密码示意图

3)配置ssh服务别名

客户端每次都输入 ssh -p port user@remote,时间久了会觉得很麻烦,特别是当 user, remoteport 都得输入,而且还不好记忆。

而给客户端配置别名可以解决这个问题,譬如用:ssh myserver 来替代上面这么一长串。要实现这个功能需要在客户端的 ~/.ssh/config (没有这个文件则手动创建)里面追加以下内容:

1
2
3
4
Host myserver
HostName 服务器ip地址
User 服务器用户名
Port 22

例如:

1
2
3
4
Host myserver
HostName 192.168.1.130
User qcmoke
Port 22

保存之后,即可用 以下命令实现快速远程登录了

1
2
3
4
$ ssh myserver

#此外对于scp命令同样可以使用myserver替代-P port user@remote了
$ scp -r demo myserver:/home

注意:ssh客户端会把你每次登陆过的计算机的公钥(public key)都记录在~/.ssh/known_hosts中。当下次登陆相同计算机时,ssh服务端会核对公钥。如果公钥不同,ssh服务端会发出警告给客户端。

一台客户端连接多个Linux系统,会经常切换,但客户端使用同一个ip,客户端登录过一次后就会把ssh信息记录在客户端本地的~/.ssh/known_hsots文件中,客户端切换其他系统后再用ssh访问原来登陆的系统就会出现冲突警告。

解决办法: 客户端直接把~/.ssh/known_hosts文件删除即可。

3. 远程文件传输

通过使用ssh客户端可以登录控制服务器了,但是想要在客户端和服务器之间进行文件传输还得需要其他的传输工具。有的是基于ssh协议的,有的基于ftp协议的,还有的是基于sftp协议等的,各有千秋。下面介绍三种工具:即SCP、FileZilla、Xftp 。

3.1 scp

scp 就是 secure copy,是基于ssh登陆进行安全的远程文件拷贝命令。只要服务器安装有ssh服务软件,客户端安装有ssh客户端软件,并建立起了连接,则可以直接使用。它的地址格式与 ssh 基本相同需要注意的是,在指定端口时用的是大写的 -P 而不是小写的。

002_SCP示意图

1
2
3
4
5
6
7
8
9
10
11
12
13
# 把本地当前目录下的 01.py 文件 复制到 远程 家目录下的 Desktop/01.py
# 注意:`:` 后面的路径如果不是绝对路径,则以用户的家目录作为参照路径
scp -P port 01.py user@remote:Desktop/01.py

# 把远程 家目录下的 Desktop/01.py 文件 复制到 本地当前目录下的 01.py
scp -P port user@remote:Desktop/01.py 01.py

# 加上 -r 选项可以传送文件夹
# 把当前目录下的 demo 文件夹 复制到 远程 家目录下的 Desktop
scp -r demo user@remote:Desktop

# 把远程 家目录下的 Desktop 复制到 当前目录下的 demo 文件夹
scp -r user@remote:Desktop demo
选项含义
-r若给出的源文件是目录文件,则 scp 将递归复制该目录下的所有子目录和文件,目标文件必须为一个目录名
-P若远程 SSH 服务器的端口不是 22,需要使用大写字母 -P 选项指定端口

注意:

scp 这个终端命令只能在 Linux 或者 UNIX 系统下使用

如果在 Windows 系统中,可以安装 PuTTY,使用 pscp 命令行工具或者安装 FileZilla 使用 FTP 进行文件传输

3.2 FileZilla

官方网站:https://www.filezilla.cn/download/client

FileZilla 在传输文件时,使用的是 FTP 服务 而不是 SSH 服务,因此端口号应该设置为 21。使用FTP服务的时候,我们都知道默认是21号端口,其实还有一个20号端口。FTP使用两个TCP连接,21号端口负责控制连接,20号端口负责数据连接。

3.3 Xftp

官方网站:https://www.netsarang.com/products/xfp_overview.html

Xftp除了使用FTP服务还使用了SFTP服务,通过使用SFTP协议连接服务器传输文件会更安全。SFTP是SSH的一部分,在SSH软件包中,已经包含了一个SFTP(Secure File Transfer Protocol)的安全文件传输子系统,SFTP本身没有单独的守护进程,它必须使用sshd守护进程(端口号默认是22)来完成相应的连接操作。由于这种传输方式使用了加密/解密技术,文件传送相对来说是很安全的,但是是有代价的,它的传输效率比FTP要低得多。

3.4 lrzsz

基于命令操作的上传下载的工具 lrzsz,目前主流的SSH连接工具 ( SecureCRT、XShell 等 ) 都支持这些协议。

1
2
3
4
5
6
7
#服务器安装
yum install -y lrzsz #centos
apt install lrzsz #ubuntu
#在客户端执行弹窗选择文件上传
rz
#在服务端执行选择文件下载(多文件sz 1.txt 2.txt)
sz a.txt

十一、磁盘管理

1. 相关基础命令

1
2
3
4
5
6
#显示磁盘分区使用情况 -h:使用人类可读的格式 -T:显示磁盘分区文件系统类型
df -h

#查看可用设备(包括磁盘等)-f 查看文件系统相关设备 -S 查看scsi设备相关设备
lsblk
lsblk -f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[root@localhost ~]# lsblk 
#TYPE:disk表示磁盘,part表示标准分区,lvm逻辑卷分区
#MOUNTPOINT:挂载点
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda #第一个磁盘 8:0 0 20G 0 disk
├─sda1 #第一个磁盘下的第一个分区 8:1 0 500M 0 part /boot
└─sda2 #第一个磁盘下的第二个分区 8:2 0 19.5G 0 part
├─centos-swap 253:0 0 2G 0 lvm [SWAP]
└─centos-root 253:1 0 17.5G 0 lvm /
sdb #第二个磁盘(没有分区) 8:16 0 10G 0 disk

#磁盘格式化后就会有文件系统类型和uuid
[root@localhost ~]# lsblk -f
NAME FSTYPE(文件系统类型)LABEL UUID MOUNTPOINT
sda
├─sda1 xfs be642956-78fe-4538-a3ab-840d6de853b7 /boot
└─sda2 LVM2_member dCCxeE-hgqX-XBLU-6AXZ-ikIJ-va94-Q5IF2D
├─centos-swap swap 653b8409-ce8f-4f98-904a-a1745d6568cc [SWAP]
└─centos-root xfs c6387d81-0587-4548-9a06-6c406ad9034a /
sdb

2. 标准分区管理

当添加了一块新磁盘后,系统是不能直接使用的,需要对磁盘进行创建分区、格式化分区、挂载分区三个步骤后才能正常使用。

1)创建分区

1
2
3
4
#可通过如下命令查看新加的磁盘其所在linux系统中的名称,假设为/dev/sdb
fdisk -l
#创建分区,对新磁盘进行分区(执行命令之后将会进行手工命令交互过程)
fdisk /dev/sdb

创建分区示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
[root@localhost ~]# fdisk /dev/sdb 
Welcome to fdisk (util-linux 2.23.2).

Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Device does not contain a recognized partition table
Building a new DOS disklabel with disk identifier 0x5a23d71f.

Command (m for help): m #查看输入选项菜单
Command action
a toggle a bootable flag
b edit bsd disklabel
c toggle the dos compatibility flag
d delete a partition
g create a new empty GPT partition table
G create an IRIX (SGI) partition table
l list known partition types
m print this menu
n add a new partition
o create a new empty DOS partition table
p print the partition table
q quit without saving changes
s create a new empty Sun disklabel
t change a partition's system id
u change display/entry units
v verify the partition table
w write table to disk and exit
x extra functionality (experts only)

Command (m for help): n #创建新分区
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p #分区类型选择为主分区
Partition number (1-4, default 1): 1 #指定分区号,如果输入1,那么分区为/dev/sdb2,2则为/dev/sdb2
First sector (2048-20971519, default 2048): 2048 #指定第一个扇区地址(2048默认值,表示从磁盘的第一个扇区,可直接回车选默认)
Last sector, +sectors or +size{K,M,G} (2048-20971519, default 20971519): 20971519 #最后一个扇区地址(默认磁盘的最大可存储地址,可直接回车选默认,如果该磁盘需要创建多个分区的话可以按照需求修改)
Partition 1 of type Linux and of size 10 GiB is set

Command (m for help): w #写入分区并退出
The partition table has been altered!

Calling ioctl() to re-read partition table.
Syncing disks.

默认使用DOS(即MBR)作为磁盘分区方案,如果需要使用GPT,那么需要在输入“n”创建分区之前先输入“g”指定为GPT分区方案,如需改回MBR方案,只需创建分区之前先输入“o”指定为MBR分区方案。

MBR只能支持最多4个主分区或3个主分区和1个扩展分区。每个主分区最多可以有一个逻辑分区,而一个扩展分区可以创建多个逻辑分区。它使用了一个512字节的扇区来存储分区表信息,由于分区表大小的限制所以只能支持到最多4个主分区。

GPT能够支持更多的分区(理论无限)。GPT没有主分区和扩展分区的概念,所有分区都是相等的,可以理解为所有的分区都是主分区。它使用64个扇区(32KB)来存储分区信息,相比之下,MBR分区表只有512字节。这使得GPT分区表能够存储更多的分区信息。

2)格式化分区

1
2
3
#格式化分区
mkfs -t ext4 /dev/sdb1
#或者mkfs.ext4 -F /dev/sdb1

3)挂载分区

挂载即将一个分区与一个目录进行关联,使操作该目录文件即操作对应的磁盘分区。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#先创建需要挂载的目录
mkdir /data
#将分区挂载到对应目录(临时挂载)
mount /dev/sdb1 /data
#最后查看挂载是否成功
df -h

#设置开机自动挂载
echo "/dev/sdb1 /data ext4 defaults 1 1" >> /etc/fstab
#或者通过分区的uuid进行挂载(查看所有分区的对应UUID,可通过命令blkid查看),如下:
echo "UUID=6f74be84-76e7-4177-a387-e2e711329c33 /data ext4 defaults 1 1" >> /etc/fstab

#挂载 /etc/fstab 配置文件里的所有文件系统以立即生效
mount -a
#或者通过重启以生效:reboot

#查看系统磁盘挂载情况
df -h

注意:如果需挂载的目录在挂载前存在文件,那么挂载后这些文件将会"消失",但卸载后这些文件就又会显现,原因是挂载前文件是存在于原来的磁盘分区上的,如果同一目录挂载了新的磁盘分区,那么该目录显示的是新磁盘分区的内容,而新分区并没有这些文件所以文件会"消失"。当卸载后,挂载目录又会回到原磁盘分区上,自然就会把原本的文件显现出来。

4)卸载及删除分区

1
2
3
4
5
6
7
8
9
10
11
12
13
##卸载
umount /dev/sdb1
#或者 umount /data
#如果是开机自动挂载的话还需要删除/etc/fstab文件对应的挂载配置


##删除分区
fdisk /dev/sdb
m
d
1
d #删除
w #输入 w 保存,这个时候分区以及删除了,可以重新创建了

参考:

https://www.cnblogs.com/zishengY/p/7137671.html

https://www.iplayio.cn/post/80157

3. LVM分区管理

1)相关概念

标准分区是指将磁盘分割成若干个区域,每个区域被称为分区。每个分区都被视为一个独立的逻辑单元,并且可以格式化为不同的文件系统类型。标准分区方案的优点是简单、直观,易于管理和维护。但是,如果需要调整分区大小或添加新的分区,则需要重新分区,并且可能需要重装操作系统,这会导致数据丢失和系统停机时间较长等问题。

LVM是一种更加灵活的磁盘分区方案,它允许将多个物理磁盘或分区设置为物理卷(PV), 然后将它们组合成一个或多个逻辑卷组(VG),然后将逻辑卷组划分为一个或多个逻辑卷(LV)。逻辑卷是一个虚拟的磁盘分区,它可以动态地调整大小和移动,而不需要重新分区或重装操作系统。此外,LVM还支持在线扩容和快照等高级特性。

与标准分区相比,LVM的优点在于它提供了更高的灵活性和可扩展性,可以动态地分配和管理存储空间,避免了重新分区和重装操作系统的繁琐过程。但是,LVM也存在一些缺点,比如它可能会降低磁盘性能,增加系统复杂度和学习成本等。因此,在选择分区方案时,需要根据实际需求和环境来进行权衡和选择。

说明:

物理卷逻辑上可划分为多个大小相同的物理拓展PE,PE是LVM中的最小分配单元,每个 PE 的大小通常为 4MB,可以在创建pv的时候指定其大小,如创建一个PE大小为8MB的物理卷/dev/sdb1:pvcreate -s 8M /dev/sdb1

LV大小为PE的整数倍,组成LV的PE可能来自不同的物理磁盘。

在LVM中,物理卷(PV)的可用大小可能小于其底层设备的大小,其中一些原因包括:

  1. LVM会在物理卷上保留一部分空间作为元数据区域,用于存储逻辑卷组(VG)和逻辑卷(LV)的元数据信息。这些元数据占用了一定的空间,从而减少了物理卷的可用空间。
  2. 物理卷使用的文件系统可能也会在设备上分配一些空间,例如ext4文件系统会在物理卷上保留一部分空间用于存储文件系统元数据和碎片信息。这些空间也会使得物理卷的可用空间减少。
  3. 如果物理卷上还有其他分区或文件系统,则它们也会占用一些空间,从而减少了物理卷的可用空间。

因此,当创建物理卷时,应该考虑到这些因素,并为物理卷预留足够的空间以供元数据和其他用途使用。

2)查看

1
2
3
4
5
6
7
8
#查看物理卷
pvs、pvdisplay、pvscan
#查看卷组
vgs、vgdisplay、vgscan
#查看逻辑卷
lvs、lvdisplay、lvscan
#查看磁盘分区
fdisk -L

3)创建 pv、vg、lv

1
2
3
4
5
6
7
8
9
10
11
12
#创建pv物理卷(设备路径可以是磁盘设备路径(/dev/sdb)或者分区设备路径(/dev/sdb1))
pvcreate 设备路径
#如:pvcreate /dev/sdb
#还可以同时创建多个pv,如:pvcreate vg名 pv1路径 pv2路径 pv3路径

#创建vg卷组
vgcreate vg名 pv路径
#如:vgcreate myvg /dev/sdb

#创建lv逻辑卷(大小可以用计量单位,比如5G,2048M等,如果设置的大小不满足pe大小的整数倍将自动进行四舍五入处理)
lvcreate -n lv名 -L 大小 vg名
#如:lvcreate -n mylv -L 5G myvg

4)格式化和挂载 lv

1
2
3
4
5
6
7
8
9
10
11
#格式化lv(lv完整路径可以通过命令lvdisplay查看)
mkfs.ext4 lv完整路径
#如:mkfs.ext4 /dev/myvg/mylv

#挂载(挂载点即需要挂载的目录,需要提前创建)
mount lv完整路径 挂载点目录路径
#如:mount /dev/myvg/mylv /mnt/mylv

#开机自动挂载
echo "lv完整路径 挂载点目录路径 ext4 defaults 1 1" >> /etc/fstab
#如:echo "/dev/myvg/mylv /mnt/mylv ext4 defaults 1 1" >> /etc/fstab

5)卸载 lv

1
2
3
#(如果有开机自动挂载配置还需要删除/etc/fstab文件对应的挂载配置)
umount lv完整路径
#如:umount /mnt/mylv

6)删除 lv、vg、pv

1
2
3
4
5
6
7
8
9
10
11
#删lv(注意:删除lv前要先将其卸载)
lvremove lv完整路径
#如:lvremove /dev/myvg/mylv

#删vg
vgremove vg名
#如:vgremove myvg

#删PV
pvremove 设备完整路径 去硬盘
#如:pvremove /dev/sdb

7)扩容

扩容 l v的时如果 vg 容量不够,需要添加 pv 并加到 vg 中然后再给 lv 扩容,否则不需要这个步骤。

1
2
3
4
5
6
7
#添加新的pv
pvcreate 设备路径
#如:pvcreate /dev/sdc

#扩展vg
vgextend vg名 新增pv路径
#如:vgextend myvg /dev/sdc
1
2
3
#扩容lv(扩展量可以用计量单位,比如3G,通过+表示扩展多少,而如果不用+则表示扩展到多少)
lvextend -L +扩展量 lv完整路径
#如:lvextend -L +3G /dev/myvg/mylv

以上只是对lv进行扩容,但文件系统是无法识别的,故需要调整文件系统容量

1
2
3
#调整文件系统容量(将文件系统扩展到逻辑卷的整个大小)
resize2fs lv完整路径
#如:resize2fs /dev/myvg/mylv

8)缩容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#首先进行卸载
umount lv完整路径
#如:umount /dev/myvg/mylv

#检查文件系统
e2fsck -f lv完整路径
#如:e2fsck -f /dev/myvg/mylv

#减少文件系统
resize2fs lv完整路径 减少到的大小
#如:resize2fs /dev/myvg/mylv 2G

#减少lv卷大小(注意:文件系统的减小后大小一定要和lv卷最终大小相等)
lvreduce -L 减少到的大小 lv的完整路径
#如:lvreduce -L 2G /dev/myvg/mylv

#重新挂载使用
mount lv完整路径 挂载点
#如:mount /dev/myvg/mylv /mnt/mylv

9)替换磁盘

在 LVS 中,替换磁盘即替换 PV,注意新 PV 容量要大于等于原 PV。

1
2
3
4
5
6
7
8
9
10
11
#设将原sda磁盘替换为新的sdb磁盘,并移除原sda磁盘,操作如下:
#先准备一个新的磁盘 pv 加入搭配 vg 中
pvcreate /dev/sdb
gextend myvg /dev/sdb
#通过pvmove命令移动原pv的数据到新的pv中
pvmove /dev/sda /dev/sdb
#从vg中移除原pv
vgreduce myvg /dev/sda
#删除原pv
pvremove /dev/sda
#如果新pv容量比原pv大,则还可以通过lvextend和resize2fs命令进行扩容

参考:

十二、时间管理

1. 查看时间

1
2
3
4
5
6
7
#查看当前系统时间
date
#指定格式查看当前系统时间
date +"%Y-%m-%d %H:%M:%S"
#查看日历,-y选项可以查看一年的日历
cal
cal 2022

2. 修改时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#修改时分秒
date -s 11:11:11
#修改年月日
date -s 2019-11-11
#修改年月日时分秒
date -s "2019-11-11 11:11:11"

#保存为bios时间(RTC)(同步BIOS时钟,强制将系统时间写入CMOS,使之永久生效,避免系统重启后恢复成原时间。)
hwclock -w
#或者
clock -w

#查看bios时间
hwclock -r

3.设置时区

1
2
3
4
5
6
7
#查看当前系统配置的时区
timedatectl | grep "Time zone" #或者:cat /etc/timezone

#显示系统中支持的所有时区列表
timedatectl list-timezones
#设置当前系统为Asia/Shanghai上海时区
timedatectl set-timezone Asia/Shanghai

4. 时间同步

4.1 单机版

1
2
3
4
5
6
#安装ntpdate
yum install ntpdate -y
#同步网络时间(要求服务器可访问外网)
ntpdate ntp1.aliyun.com
#保存为bios时间(RTC)
hwclock -w

4.2 集群版

方案:集群中,要求有一台能访问外网的服务器作为时间服务器,其余内网服务器通过这台时间服务器来实现时间同步。有两种常用的服务工具实现:ntp和chrony

注意:这里ntp和chrony相比于ntpdate的区别在于,ntpdate只能手动单次同步时间(除非编写cronp配置),其同步时间的速度是很快的。而ntp和chrony本身就可以自己定时同步时间,其同步时间的速度可能需要几分钟以上。

全球相关ntp时间服务器:https://www.ntppool.org/zh/

4.2.1 ntp

(1)安装和环境准备

1
2
3
4
5
6
7
8
#安装ntp
yum install ntp -y

#开放123端口防火墙作为客户端访问的端口
firewall-cmd --permanent --add-port=123/udp
firewall-cmd --reload
#使用前可以把其他时间同步服务关掉,比如chrony(如果有使用的话)
systemctl stop chronyd && systemctl disable chronyd

(2)修改ntp参数配置文件

🙆‍♂对于ntpd,发现这里不做配置也可以自动同步硬件时间。

1
2
3
vim  /etc/sysconfig/ntpd
#可选择修改,是让ntpdate同步时候时写到硬件
vim /etc/sysconfig/ntpdate

修改或者追加如下配置

1
2
#同步时间后,写到硬件中
SYNC_HWCLOCK=yes

(3)修改ntp配置文件

1
2
#修改ntp配置文件(只做以下相关配置修改,其余保持不变)
vim /etc/ntp.conf

服务端配置

1
2
3
4
5
6
7
8
9
10
11
#允许192.168.60.0网段内所有机器从本机同步时间
restrict 192.168.60.0 mask 255.255.255.0 nomodify notrap
#时间服务器地址
server 0.centos.pool.ntp.org iburst
server ntp1.aliyun.com iburst
#允许上层时间服务器主动修改本机时间
restrict 0.centos.pool.ntp.org nomodify notrap noquery
restrict ntp1.aliyun.com nomodify notrap noquery
#外部时间服务器不可用时,以本地时间作为时间服务
server 127.127.1.0
fudge 127.127.1.0 stratum 10

客户端配置

1
2
3
4
5
6
7
#从node1中同步时间
server 192.168.60.101 iburst
#允许node01修改本地时间
restrict 192.168.60.101 nomodify notrap noquery
#如果node01不可用,用本地的时间服务
server 127.127.1.0
fudge 127.127.1.0 stratum 10

(4)启动和测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#ntpd进程进行同步时,可能需要5-10分钟的时间才能同步,另外ntpd开启后,则无法使用ntpdate,所以可以提前先手动同步
ntpdate ntp1.aliyun.com
#ntpdate 192.168.60.101
hwclock -w

#启动服务
systemctl start ntpd
#开机启动
systemctl enable ntpd
netstat -tunlp |grep ntpd

##上层 ntp 的状态
#*表示目前使用的ntp server
#remote:用于同步的远程节点或服务器。“LOCAL”表示本机(当没有远程服务器可用时会出现)
#refid:远程的服务器进行同步的更高一级服务器
#st:即stratum阶层,值越小表示ntp serve的精准度越高
#when:最后一次同步到现在的时间
#Poll表示,每隔多少毫秒与ntp server同步一次
#reach:已经成功更新的次数
#delay:从本地到远程节点或服务器通信的往返时间
#offset:主机与远程节点或服务器时间源的时间偏移量,offset 越接近于0,主机和 NTP 服务器的时间越接近(以方均根表示,单位为毫秒)
#jitter:与远程节点同步的时间源的平均偏差(多个时间样本中的 offset 的偏差,单位是毫秒),这个数值的绝对值越小,主机的时间就越精确
ntpq -p
#可通过watch来实时监控
watch ntpq -p

#ntp 同步状态(等待5-10分钟后,查看同步状态)
ntpstat

#查看日志
tail -f /var/log/messages
4.2.2 chrony

(1)安装和环境准备

1
2
3
4
5
6
7
8
9
#安装chrony
yum install chrony -y

#开放123端口防火墙作为客户端访问的端口
firewall-cmd --permanent --add-port=123/udp
firewall-cmd --permanent --add-port=323/udp
firewall-cmd --reload
#使用前可以把其他时间同步服务关掉,比如ntp(如果有使用的话)
systemctl stop ntpd && systemctl disable ntpd

(2)修改chrony配置文件

1
2
#修改配置文件(只做以下相关配置修改,其余保持不变)
vim /etc/chrony.conf

服务端配置

假设服务端ip为192.168.60.101

1
2
3
4
5
6
7
8
9
#外网ntp时间服务器地址
server 0.centos.pool.ntp.org iburst
server ntp1.aliyun.com iburst
#同步到bios时间(RTC)
rtcsync
#限制允许192.168.60网段ip的客户端同步
allow 192.168.60.0/24
#即使未与时间源同步也可提供本地时间
local stratum 10

客户端配置

1
2
3
4
# 删除其它server,并添加如下server
server 192.168.60.101 iburst
#同步到bios时间(RTC)
rtcsync

(3)启动和测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#启动服务
systemctl start chronyd
#测试时间同步的时候(假设手动设置了错误的时间)如果chronyd已经启动了的话,需要重启以下才能看效果
systemctl restart chronyd
#开机启动
systemctl enable chronyd
netstat -tunlp |grep chronyd

#强制快速同步系统时间
chronyc -a makestep
hwclock -w

#chrony兼容ntpdate,客户端也可以使用ntpdate手动快速同步时间
ntpdate 192.168.60.101

5. 定时任务

1)用户定时任务

每个用户都可以创建自己的定时任务,这些任务仅对该用户可见和执行。用户定时任务通常存储在/var/spool/cron目录里。都是以用户名命名的子目录里。

  • 在 RedHat 系列系统里,用户的定时任务配置文件(也称为 crontab 文件)存储在 /var/spool/cron/ 目录中。每个用户的定时任务都保存在相应的用户名文件中,例如,root 用户的定时任务文件位于/var/spool/cron/root
  • 在 Debian 系列系统里,用户的定时任务配置文件同样是 crontab 文件,存储在 /var/spool/cron/crontabs/ 目录中。每个用户的定时任务都保存在相应的用户名文件中,例如,root用户的定时任务文件位于 /var/spool/cron/crontabs/root
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
##用户定时任务的配置格式
m h dom mon dow command

#编辑用户定时任务
crontab -e

##示例:
#(1)每天凌晨2点执行命令
0 2 * * * command

#(2)每周一到周五的上午9点执行命令
0 9 * * 1-5 command

#(3)每个月的1号和15号的下午3点执行命令
0 15 1,15 * * command

#(4)每小时的第10分钟执行命令
10 * * * * command

#(5)每隔5分钟执行命令
*/5 * * * * command
#每1分钟执行一次任务
* * * * * command #同:*/1 * * * * command

💁‍♂ cron 表达式说明:

定时任务的语法由五个时间字段和一个命令字段组成,用于指定任务执行的时间间隔和要执行的命令。

  • m:分钟(minute:0-59)
  • h:小时(hour:0-23)
  • dom:月份中的某一天(day of month:1-31)
  • mon:月份(month:1-12)
  • dow:星期中的某一天(day of week:0-7,其中0和7都表示星期日)
  • command:要执行的命令或脚本路径

特殊的字符和符号:

  • 星号(*):通配符,表示匹配所有可能的值。例如,*表示每分钟、每小时、每天、每月、每周都执行。
  • 逗号(,):用于列举多个值。例如,1,5,10表示1、5和10这三个值。
  • 连接符(-):用于定义范围。例如,3-6表示从3到6的连续值。
  • 斜线(/):用于定义步长。例如,*/5表示每隔5个单位执行一次。对于分钟字段,*/5表示每隔5分钟执行一次。

💁‍♂ 注意:用户定时任务只能强制以用户身份运行,不能指定执行任务的用户

2)系统定时任务

系统定时任务对整个系统生效。这些任务只有 root 用户或具有 sudo 权限的用户才能管理维护,系统级别的 crontab 文件通常存储在 /etc/crontab/etc/cron.d/ 目录中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
##系统定时任务的配置格式
m h dom mon dow user command

#编辑系统定时任务
vi /etc/crontab

##示例:
#(1)每天凌晨2点执行命令
0 2 * * * root command

#(2)每周一到周五的上午9点执行命令
0 9 * * 1-5 root command

#(3)每个月的1号和15号的下午3点执行命令
0 15 1,15 * * root command
  • user:执行命令的用户(默认以 root 用户身份运行,但可以指定其他用户身份运行)

十三、Shell编程

1. sed 命令工具

  • 偏向场景是以流处理的方式编辑文档

  • 处理方式:以行处理

sed是一种几乎包括在所有 UNIX 平台(包括 Linux)的轻量级流编辑器。sed主要是用来将数据进行选取、替换、删除、新增的命令。

1.1 格式

1
sed [选项] '[ 匹配地址 [!] 动作]' 文件名

!表示对匹配地址的行不执行动作

匹配地址可以是:

(1)模式匹配地址,即正则表达式

(2)行数范围,写数字

常用选项

-n: 一般sed命令会把所有数据都输出到屏幕 ,如果加入此选择,则只会把经过sed命令处理的输出到屏幕。
-e: 允许对输入数据应用多条sed命令编辑
-i: 用sed的修改结果直接修改读取数据的文件,而不是由屏幕输出(即会修改源数据)

动作(作用于行)

a \追加,在当前行后添加一行或多行。添加多行时,除最后 一行
外,每行末尾需要用“\”代表数据未完结。
c \行替换,用c后面的字符串替换原数据行,替换多行时,除最
后一行外,每行末尾需用“\”代表数据未完结。
i \插入,在当期行前插入一行或多行。插入多行时,除最后 一行
外,每行末尾需要用“\”代表数据未完结。
d删除,删除指定的行。
p打印,输出指定的行。
s字串替换,用一个字符串替换另外一个字符串。格式为“行范。(作用于行中的字符串)
s/旧字串/新字串/g”(和vim中的替换格式类似)

1.2 在第二行后追加一行内容

1
$ sed -i '2a s003,\tlisi,\tjava,\t100,\tok,' student.txt #不加-i则会输出到屏幕(即不修改原文件的内容),加了-i则会输出会原文件以覆盖原内容

1542620949919

1.2 在第二行前追加两行内容

1
2
3
$ sed '2i \
s004,\twangwu,\tjava,\t100,\tok, \
s005,\tzhaosi,\tc++,\t100,\tok,' student.txt

1542622161517

\表示输入未结束

1.3 打印行

1
$ sed -n '2 p' student.txt  #只打印第二行,-n防止打印第二行后还会打印所有行  #此处的2是行数匹配地址

1542620106443

1.4 删除行

删除第二行到第三行(不改变源文件的数据,只输出删除后剩余的结果)

1
$ sed '2,3d' student.txt

1542620284091

删除第一行并修改文本源数据(将输出结果覆盖作用的文件内容)

1
$ sed -i '1d' student.txt

1542620470315

1.5 字符串替换

sed ' 匹配地址 s/旧字串/新字串/g' 文件名

此处匹配地址如果是正则匹配地址,那么一定要加/ /以表示正则模式

把第二行的wen改成xuan

1542622690522

2. awk 命令工具

  • 偏向场景是以流处理的格式化报表输出

  • 处理方式:以行处理

2.1 格式

1
awk  '条件1{动作1}  条件2{动作2}  …'  文件名

条件(Pattern):
一般使用关系表达式作为条件
x > 10 判断变量 x是否大于10
x>=10 大于等于
x<=10 小于等于
动作(Action):
格式化输出
流程控制语句

如果没有指定条件,每行都执行相应的动作

所有的动作或者命令都要用{}括起来

测试文件:student.txt:

1
2
3
4
s001,	wen,	java,   90,	ok,
s001, wen, c, 90, ok,
s001, wen, c#, 90, ok,
s002, qcmoke, c, 100, ok,
2.1.1 输出第一列和第二列
1
2
3
$ awk '{print $1$2}' student.txt
# $1为取出第一个分隔开的字段,$2为取出第二个分隔开的字段
# 默认识别的分隔符是制表符或者大于零的任意空格

1542617270519

2.2 BEGIN

BEGIN是在所有的数据读取之前的命令语句,以是否执行成功为条件结果,满足BEGIN才执行{}里的内容

2.2.1 测试BEGIN
1
$ awk 'BEGIN{print "hello"} {print $1  "\t"  $2}' student.txt

1542617203006

2.3 FS内置对象

作用:给awk命令设置识别的分隔符

1
$ awk '{FS=","} {print $1 "\t" $2}' student.txt

1542618027330

awk默认是先读入一行数据才开始处理后面的动作,故在指定分隔符后,从第二行开始才生效,而第一行无效。

处理:

2.3.1 测试FS

使用BEGIN,让awk读取第一行数据前就先指定分隔符。

1
$ awk 'BEGIN{FS=","} {print $1 "\t" $2}' student.txt

1542618296511

2.4 END

作用:在所有数据都读取并执行完所有动作之后再执行某个动作,以是否成功为条件结果。

2.4.1 测试END
1
$ awk '{print $1$2}END{print "ending over !"}' student.txt

1542618618673

3. 通过 cat 命令在文件末尾追加内容(并防止重复添加)

示例如下:

1
2
3
4
5
6
7
8
9
10
11
#在/etc/bash.bashrc文件末尾配置export LC_ALL="C.UTF-8"
text_str='export LC_ALL="C.UTF-8"' ;\
file_str='/etc/bash.bashrc' ;\
grep -v '^#' "$file_str" | grep -q "$text_str" || cat >> "$file_str" << EOF
$text_str
EOF

#或者:
text_str='export LC_ALL="C.UTF-8"' ;\
file_str='/etc/bash.bashrc' ;\
grep -v '^#' "$file_str" | grep -q "$text_str" || echo "$text_str" >> "$file_str"

十四、vi 和 vim

基本使用

vi和vim的三种模式:

1
2
3
正常模式:以 vim 打开一个档案就直接进入一般模式了(这是默认的模式)。在这个模式中, 你可以使用『上下左右』按键来移动光标,你可以使用『删除字符』或『删除整行』来处理档案内容, 也可以使用『复制、粘贴』来处理你的文件数据。
插入模式:按下 i, I, o, O, a, A, r, R 等任何一个字母之后才会进入编辑模式, 一般来说按 i 即可.
命令行模式:即先按 esc 键再输入 :时的情况。可以提供你相关指令,完成读取、存盘、替换、离开vim、显示行号等的动作则是在此模式中达成的!

各种模式的相互切换如图:

image-20230319063455443

常用操作如下:

1
2
3
4
5
6
7
1) 拷贝行:在一般模式下, yy 拷贝当前行(5yy 拷贝当前行向下的 5 行),输入 p 进行粘贴。
2) 删除行:删除当前行 dd ;删除当前行向下的 5 行 5dd
3) 查找某个单词:命令行下,/关键字 , 回车 查找,输入n就是查找下一个,输入N向上查找下一个
4) 设置文件的行号,取消文件的行号:在一般模式下, :set nu 和 :set nonu
5) 将光标移动到文档首行和末行:在一般模式下,末行[G],首行[gg]
6) 撤销:在一个文件中输入内容后,在一般模式下, 撤销按 u
7) 将光标移动到指定行:在一般模式下,先输入行号(如20),再按 shift + g

更多命令操作见下图:

vi-vim-cheat-sheet-sch

参考:https://www.runoob.com/linux/linux-vim.html

常见问题

(1)解决使用 vi 或 vim 粘贴导致缩进问题或乱码

这是由于 vi 或 vim 对于某些格式的文件(如:yaml 文件)进行粘贴时进行了自动格式化处理,为了防止自动格式化可如下解决:

  • 在命令模式下,输入 :set paste 并回车确认,然后再输入 i 进行粘贴。
  • 如需恢复自动缩进只需在命令模式输入 :set nopaste 即可

十五、Linux安装

自定义磁盘分区

在安装Linux时,以下分区是必须要创建的:

  1. 根分区(/):这是Linux系统的根目录,包含操作系统的所有文件和目录。
  2. 交换分区(swap):用于虚拟内存,当物理内存不足时,系统将部分数据移至交换分区中(通常建议将交换分区大小设置为物理内存的两倍)。

如果使用UEFI启动,则还需要创建一个EFI系统分区(ESP),它包含引导加载程序、内核文件和其他支持文件。但是,如果使用传统的BIOS引导模式,则不需要创建ESP分区。

需要注意的是,在某些情况下,可能会出现不需要 ESP 分区也可以使用 UEFI 启动的情况。例如,某些 UEFI 固件可能支持直接从磁盘中的某个分区启动操作系统,而无需使用 ESP 分区。此外,一些特定的发行版或安装程序可能提供了与 ESP 分区无关的替代方案,以便在没有 ESP 分区的情况下实现 UEFI 启动

请注意,以上仅适用于基本的Linux安装。而为了数据的安全,通常会创建以下几个分区

  • 根分区(/)
  • 交换分区(swap)
  • /home 分区:用于存储用户数据和配置文件。
  • /boot 分区:通常用于存储启动引导程序、内核映像以及相关的配置文件等。需要足够的空间来存储未来更新的内核文件。
  • EFI 系统分区(ESP):如果使用UEFI启动,则需要一个ESP分区,它包含引导加载程序、内核文件和其他支持文件,在l安装inux后会自动挂载到系统的/boot/efi目录。

在某些情况下,还可能需要创建其他分区,如/var/tmp/usr 分区等。但这取决于具体的需求和Linux发行版的要求。

**分区容量分配示例:**对于一个 100GB 容量的磁盘,建议将其分区和配置如下:

  1. 根分区(/):将根分区设置为 40-50GB。这足以安装Linux系统、常用应用程序和一些基本的开发工具。
  2. 交换分区(swap):将交换分区设置为 2-4GB。这里推荐使用物理内存大小的两倍作为交换分区大小的基准。
  3. /home 分区:将/home分区设置为 30-50GB。这将为用户数据和配置文件提供足够的存储空间。
  4. /boot 分区:设置 2GB(至少 200MB,但考虑到可能需要升级内核或者自编译内核等可能需要较多空间,则建议设置为 2GB,防止升级内核时出现分区空间不足的问题),要确保足够存储未来的内核更新文件。
  5. EFI 系统分区(ESP):如果您使用 UEFI 引导,则需要创建一个 ESP 分区。通常,这个分区只需要为 100-500MB 即可。
  6. 其他分区:如果您需要存储大量的数据、音频或视频文件,可以创建一个单独的数据分区。该分区的大小应根据您的特定需求来确定。

提示:如果没有特别需求,其实只分配根分区和交换分区就够了。

十六、常见问题解决

1. linux更新被锁的解决方法

1
2
3
4
5
6
#问题如下:
E: 无法获得锁 /var/lib/dpkg/lock - open (11: 资源暂时不可用)
E: 无法锁定管理目录(/var/lib/dpkg/),是否有其他进程正占用它?

#解决:
rm /var/lib/dpkg/lock

2. 解决使用ls命令目录无法高亮显示的问题

1
2
3
4
5
6
cat >> ~/.bashrc << 'EOF'
alias ls='ls --color=auto'
EOF

#使配置文件修改生效
source ~/.bashrc


----------- 本文结束 -----------




如果你觉得我的文章对你有帮助,你可以打赏我哦~
0%