一、总结软件管理相关指令
1.1 相关概念
1.1.1 什么是软件包管理
| 层级 | 工具 | 职责 |
|---|---|---|
| 包管理器(上层) | dnf/apt | 自动解决依赖关系.从仓库下载,调用底层工具 |
| 底层工具(下层) | rpm/dpkg | 真正执行安装,卸载,查询等操作 |
1.1.2 包管理体系
| 体系 | 软件包格式和后缀 | 管理器 | 仓库配置文件 | 说明 |
|---|---|---|---|---|
Debian/Ubuntu | .deb | apt | /etc/apt/sources.list | Ubuntu原生仓库默认会对接国内仓库,如无特殊需求,无需配置 |
REHL/CentOS/Rocky | .rpm | dnf | /etc/yum.repos.d/ | 红帽原生仓库在国外,一般需要配置国内仓库 |
1.2 dnf 包管理器
1.2.1 核心命令
| 操作 | 命令 (以nginx为例) | 说明 |
|---|---|---|
| 安装 | dnf install nginx | 安装(自动解决依赖) |
| 卸载 | dnf remove nginx | 删除软件包 |
| 更新 | dnf update nginx | 更新指定软件包,生产环境慎用 |
| 更新所有 | dnf update | 更新所有已安装包,生产环境慎用 |
| 搜索 | dnf search nginx | 按关键字搜索 |
| 查找提供文件的包 | dnf provides */nginx | 查找提供某文件的包 |
| 查看信息 | dnf info nginx | 显示包详细信息 |
| 查看已安装 | dnf list nginx | 列出指定已安装包 |
| 查看已安装 | dnf list installed | 列出所有已安装包 |
| 查看可用 | dnf list available | 列出可用包 |
| 包组管理 | dnf groupinstall "Development Tools" | 安装指定包组 |
1.2.2 最小安装推荐软件包
| 软件包名称 | 命令 | 说明 |
|---|---|---|
vim | vim | 高级版文本编辑器 |
bash-completion | Tab键自动补全,重连终端生效 | |
lrzsz | rz/sz | 终端快捷传输文件,传入时直接拖入终端窗口,传出时使用 sz 文件名 弹出窗口选择保存位置 |
安装命令: dnf install -y vim bash-completion lrzsz
1.2.3 常用命令示例
# 安装软件
dnf install -y nginx
# 卸载软件
dnf remove -y nginx
# 搜索
dnf search nginx
# 查找提供某文件的包
dnf provides */rz
# 查看信息
dnf info nginx
# 查看所有版本
dnf list nginx --showduplicates
# 查看历史
dnf history
# 撤销历史操作
dnf history undo 5
# 重做历史命令
dnf history redo 5
# 清理缓存
dnf clean all
1.2.4 包组管理
# 列出所有包组
dnf group list
# 查看包组详情,包含的软件包
dnf group info "Development Tools"
# 安装包组
dnf groupinstall "Development Tools"
# 安装开发工具
dnf groupinstall -y "Development Tools"
dnf install -y gcc gcc-c++ make cmake
1.3 apt 包管理器
1.3.1 核心命令
| 操作 | 命令 (以nginx为例) | 说明 |
|---|---|---|
| 更新源 | apt update | 更新软件包列表,安装软件包前操作 |
| 升级 | apt upgrade | 升级所有已安装软件包 |
| 安装 | apt install nginx | 安装软件包 |
| 卸载 | apt remove nginx | 卸载(保留配置) |
| 彻底卸载 | apt purge nginx | 卸载所有 |
| 搜索 | apt search nginx | 按关键字搜索 |
| 查看信息 | apt list nginx | 显示软件包信息 |
| 查看信息 | apt show nginx | 显示软件包详细信息 |
| 自动删除 | apt autoremove | 删除不需要的依赖 |
| 自动清理 | apt autoclean | 删除下载的缓存文件(.deb) |
1.3.2 常用命令示例
# 更新软件包列表
apt update
# 安装软件包
apt install -y nginx
# 卸载软件包
apt remove nginx
apt purge nginx
# 查看信息
apt list nginx
apt show nginx
# 自动清理
apt autoremove
apt autoclean
# 列出可安装的版本
apt-cache madison mysql-server
# 安装指定版本
apt install mysql-server=8.0.36-2ubuntu3
1.4 RPM/DEB 包本地安装
1.4.1 rpm 命令 (REHL/CentOS/Rocky)
# 测试用dnf缓存包到本地使用rpm本地安装,生产环境用于给离线服务器安装软件
dnf install -y --downloadonly --downloaddir=/tmp/rpms wget
dnf install -y --downloadonly --downloaddir=/tmp/rpms nginx
# 安装本地rpm包(不带依赖)
rpm -ivh /tmp/rpms/wget-1.24.5-5.el10.x86_64.rpm
# 安装本地rpm包(带依赖),同时安装所有包
rpm -ivh /tmp/rpms/*.rpm
# 安装本地rpm包(带依赖),同时安装指定软件包及其依赖的软件包
rpm -ivh /tmp/rpms/nginx-1.26.3-6.el10_2.5.x86_64.rpm /tmp/rpms/nginx-core-1.26.3-6.el10_2.5.x86_64.rpm /tmp/rpms/nginx-filesystem-1.26.3-6.el10_2.5.noarch.rpm /tmp/rpms/rocky-logos-httpd-100.5-3.el10.noarch.rpm
# 查询所有已安装的软件包,等同于dnf list installed
rpm -qa
rpm -qa | grep nginx
# 查询指定已安装软件包
rpm -q nginx
# 查询软件包安装的文件
rpm -ql nginx
# 查看文件由哪个软件包安装
rpm -qf /usr/lib/systemd/system/nginx.service
# 查询已安装软件包详细信息
rpm -qi nginx
# 卸载,需要按顺序卸载,先卸载软件包,后卸载被依赖的软件包
rpm -e nginx
rpm -e nginx-filesystem nginx-core rocky-logos-httpd
1.4.2 rpm 包依赖缺失处理
方法一: 离线服务器处理,在联网服务器缓存软件包时默认带依赖缓存,将软件包和依赖包完整拷贝到离线服务器安装所有包
方法二: 在线服务器处理,使用dnf localinstall安装本地包,缺失依赖自动从在线仓库获取
dnf localinstall /tmp/rpms/nginx-1.26.3-6.el10_2.5.x86_64.rpm
1.4.3 dpkg 命令(Debian/Ubuntu)
# 安装本地deb包
dpkg -i *.deb
# 列出所有已安装软件包
dpkg -l
dpkg -l | grep nginx
# 查询软件包安装的文件
dpkg -L nginx
# 查看文件由哪个软件包安装
dpkg -S /usr/sbin/nginx
# 查询已安装软件包详细信息
dpkg -s nginx
# 卸载
dpkg -r nginx # 保留配置
dpkg -P nginx # 彻底卸载
1.5 仓库配置
1.5.1 dnf 仓库配置 (REHL/CentOS/Rocky)
dnf 仓库默认仓库在国外,访问速度不佳
配置镜像仓库解决加速访问和软件获取的问题
配置方法有2种
1.5.1.1 使用镜像站提供配置方法配置
以阿里云 Rocky 镜像为例
# 全局将官方域名替换为阿里云域名
sed -e 's|^mirrorlist=|#mirrorlist=|g' \
-e 's|^#baseurl=http://dl.rockylinux.org/$contentdir|baseurl=https://mirrors.aliyun.com/rockylinux|g' \
-i.bak \
/etc/yum.repos.d/rocky-*.repo
# 清除缓存
dnf makecache
1.5.1.2 手动创建一份仓库配置文件
1.5.1.2.1 原配置文件备份
# 仓库配置文件路径
ls /etc/yum.repos.d/
# 备份原配置
mkdir /etc/yum.repos.d/backup
mv /etc/yum.repos.d/*.repo /etc/yum.repos.d/backup/
1.5.1.2.2 写入配置文件
配置文件可参考以下命令,或从网上搜索教程,或向AI索取一份配置文件
# 阿里云镜像
cat > /etc/yum.repos.d/dnf-aliyun.repo << 'EOF'
[BaseOS]
name=BaseOS
baseurl=https://mirrors.aliyun.com/rockylinux/$releasever/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever
[AppStream]
name=AppStream
baseurl=https://mirrors.aliyun.com/rockylinux/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever
[CRB]
name=CRB
baseurl=https://mirrors.aliyun.com/rockylinux/$releasever/CRB/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever
[extras]
name=extras
baseurl=https://mirrors.aliyun.com/rockylinux/$releasever/extras/$basearch/os/
gpgcheck=1
enabled=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever
[epel]
name=epel
baseurl=https://mirrors.aliyun.com/epel/$releasever/Everything/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://mirrors.aliyun.com/epel/RPM-GPG-KEY-EPEL-$releasever
EOF
dnf clean all
dnf makecache
# 清华大学镜像
cat > /etc/yum.repos.d/rocky.repo << 'EOF'
[baseos]
name=Rocky Linux $releasever - BaseOS
baseurl=https://mirrors.tuna.tsinghua.edu.cn/rocky/$releasever/BaseOS/$basearch/os/
gpgcheck=1
enabled=1
countme=1
metadata_expire=6h
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever
[appstream]
name=Rocky Linux $releasever - AppStream
baseurl=https://mirrors.tuna.tsinghua.edu.cn/rocky/$releasever/AppStream/$basearch/os/
gpgcheck=1
enabled=1
countme=1
metadata_expire=6h
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever
[extras]
name=Rocky Linux $releasever - Extras
baseurl=https://mirrors.tuna.tsinghua.edu.cn/rocky/$releasever/extras/$basearch/os/
gpgcheck=1
enabled=1
countme=1
metadata_expire=6h
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-Rocky-$releasever
[epel]
name=Extra Packages for Enterprise Linux $releasever - $basearch
baseurl=https://mirrors.tuna.tsinghua.edu.cn/epel/$releasever/Everything/$basearch/
enabled=1
gpgcheck=1
gpgkey=https://mirrors.tuna.tsinghua.edu.cn/epel/RPM-GPG-KEY-EPEL-$releasever
EOF
dnf clean all
dnf makecache
1.5.1.2.3 添加第三方软件官方源
cat > /etc/yum.repos.d/nginx.repo << 'EOF'
[nginx-stable]
name=nginx stable repo
baseurl=https://nginx.org/packages/centos/$releasever/$basearch/
gpgcheck=1
enabled=1
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
[nginx-mainline]
name=nginx mainline repo
baseurl=https://nginx.org/packages/mainline/centos/$releasever/$basearch/
gpgcheck=1
enabled=0
gpgkey=https://nginx.org/keys/nginx_signing.key
module_hotfixes=true
EOF
# 查看仓库列表
dnf repolist
# 查看可安装nginx版本,新增由nginx-stable提供版本
dnf list nginx --showduplicates
1.5.1.3 dnf 仓库管理
# 查看仓库列表
dnf repolist
# 查看所有仓库状态,包括禁用的仓库
dnf repolist --all
# 禁用/启用仓库]
dnf --disablerepo=baseos install nginx
dnf --enablerepo=nginx-mainline
1.5.2 apt 仓库配置
Ubuntu原生仓库默认会通过DNS解析为国内镜像仓库,如无特殊需求,无需配置
1.7 缓存软件包
常用于给离线服务器安装软件包
先在联网服务器缓存软件包,拷贝到离线服务器用本地安装命令安装
会自动缓存软件包和依赖包
Rocky
# 下载到默认缓存目录 /var/cache/dnf
sudo dnf install --downloadonly nginx
# 下载到指定目录
dnf install -y --downloadonly --downloaddir=/tmp/rpms wget
dnf install -y --downloadonly --downloaddir=/tmp/rpms nginx
# 清理缓存软件包
dnf clean packages
Ubuntu
# 下载到默认缓存目录 /var/cache/apt/archives/
apt update
sudo apt install -y --download-only wget
sudo apt install -y --download-only nginx
ls /var/cache/apt/archives/
# 清理缓存软件包
sudo apt clean
二、完成find命令的总结
2.1 基本语法
find [查找路径] [查找方式] [执行动作]
# 在/var/log/目录查找 .log 文件
find /var/log/ -name "*.log"
# 在根目录查找大于 100M 的文件
find / -size +100M
# 查找 7天前 的日志并删除
find /var/log/ -name "*.log" -mtime +7 -delete
2.2 查找方式
2.2.1 -name 按文件名
# 环境准备
apt install -y nginx
# 精确匹配
find /etc/ -name "nginx.conf"
# 查找以 .conf 结尾的文件
find /etc/nginx -name "*.conf"
# 查找以 nginx 开头的文件
find /etc/ -name "nginx*"
# 查找以 .log 结尾的文件
find /var/log/ -name "*.log"
# 查找包含 error 的文件
find /var/log/ -name "*error*"
2.2.2 -iname 按文件名(不区分大小写)
find /var/log/ -iname "*.LOG"
find /var/log/ -iname "*Nginx*"
2.2.3 -type 按文件类型查找
| 类型 | 含义 |
|---|---|
f | 普通文件 |
d | 目录 |
l | 符号链接 |
b | 块设备文件 |
c | 字符设备文件 |
# 查找所有目录
find /var/log -type d
# 查找所有文件
find /etc -type f
# 查找所有符号链接
find /usr/bin -type l
# 查找所有配置文件
find /etc/ -type f -name "*.conf"
# 限制最大搜索层级
find /etc/ -type d -maxdepth 1
# 统计/etc目录下所有的目录和软链接总个数
sudo find /etc/ \( -type d -o -type l \) -ls | wc -l
2.2.4 -size 按文件大小查找
| 符号 | 含义 | 示例 |
|---|---|---|
+ | 大于 | +100M 大于 100M |
- | 小于 | -size +20M -size -50M 大于 20M 小于 50M |
# 查找大于 50M 的文件
find / -type f -size +50M
# 查找大于 20M 小于 50M 的文件
find / -type f -size +20M -size -50M
# 查找大于 50M 的文件并显示大小
find / -type f -size +50M -exec ls -lh {} \;
2.2.5 -mtime 按时间查找
| 选项 | 含义 | 说明 |
|---|---|---|
-mtime | 修改时间 | 文件内容被修改的时间 |
-ctime | 改变时间 | 文件属性(权限,属主)被修改的时间 |
-atime | 访问时间 | 文件被读取的时间 |
-mmin | 修改时间(分钟) | |
-cmin | 改变时间(分钟) | |
-amin | 访问时间(分钟) |
| 符号 | 含义 | 示例 |
|---|---|---|
+ | 大于(超过) | +7 7天前 |
- | 小于(以内) | -7 七天内 |
= | 等于(正好) | 7 正好7天前 |
# 查找 7天 内修改过的文件
find /var/log/ -type f -mtime -7
# 查找 7天 前修改过的文件
find /var/log/ -type f -mtime +7
# 查找正好 7天 前修改过的文件
find /var/log/ -type f -mtime 7 -exec ls -l {} \;
# 查找 30分钟 内修改过的文件
find /var/log/ -type f -mmin -30
# 查找超过 1天 未访问的文件
find /home -type f -atime +1
# 查找 2小时 内访问过的配置文件
find /etc/ -type f -name "*.conf" -amin -120
2.2.6 -perm 按权限查找
# 按精确权限查找
find /etc/ -perm 644 -ls
# 查找所有 777 权限的文件(不安全文件)
find / -type f -perm 777
权限扩展查找:
| 符号 | 含义 | 示例 |
|---|---|---|
- | 至少包含 AND | -644 所有权限至少包含 644 |
/ | 任意一位匹配 OR | /644 属主,属组,其他人至少有一位用户权限匹配 |
# 至少满足644
find /etc -perm -644 -ls
# 至少一位用户权限满足644
find /etc -perm /644 -ls
# 查找所有可执行文件
find /usr/bin/ -type f -perm /111
# 查找所有其他用户可写的文件(存在安全风险)
find / -type f -perm 002
2.3 执行动作
2.3.1 常见动作
| 动作 | 含义 |
|---|---|
-print | 打印(默认) |
-ls | 以长格式打印,类似ls -l |
-delete | 删除 |
-exec | 执行命令 |
-ok | 交互式执行 |
# 两条命令都是查找属主具有读写权限的文件,只是写法不同
find /etc -perm -u=rw -ls
find /etc -perm -600 -ls
# 查找所有人具有写权限的文件
find /etc -perm -a=w -ls
find /etc -perm -222 -ls
# 查找其他人具有写权限的文件
find /etc -perm -o=w -ls
find /etc -perm -002 -ls
2.3.2 -exec
# 语法格式: -exec 命令 {} \;
# {} 代表查找到的文件
# \; 表示命令结束
# 查找并删除
find . -iname "*.zip" -exec rm -rf {} \;
# 查找并复制
find /etc -iname "nginx.conf" -exec cp -a {} /var/tmp/ \;
# 查找大文件并显示详细信息
find / -type f -size +100M -exec ls -lh {} \;
2.4 find 与 xargs 结合使用
2.4.1 xargs 核心作用
- 凑批: 把一堆文件名凑在一起一次性传给命令,少启动几次进程
- 解决参数太长: 有些命令一次接受不了太多参数, xargs 会自动分批
- 让管道更有用: 很多命令不支持从管道读取数据, xargs 充当桥梁
2.4.2 xargs 常用选项
-I: 替换字符串
-0: 处理空字符分隔
2.4.3 实战案例
2.4.3.1 删除文件
# 准备测试环境
mkdir dir1
touch dir1/file{1..10}.txt
ls dir1
# 先用ls -l 预览要操作的文件(安全习惯)
find dir1 -iname "file*.txt" | xargs ls -l
# 确认无误执行删除
find dir1 -iname "file*.txt" | xargs rm
# 验证结果
ls dir1/
核心知识点:
- xargs 把参数追加到命令末尾
- 删除前先预览,避免误删
2.4.3.2 -I {} 占位符替换,复制文件
# 准备测试环境
mkdir dir2
touch dir2/file{1..10}.txt
ls dir2
# 使用 {} 作为占位符
find dir2 -name "file*.txt" | xargs -I {} cp -a {} /var/tmp/
ls -l /var/tmp/file*.txt
# 使用自定义占位符
find dir2 -name "file*.txt" | xargs -I test cp -a test /var/
ls -l /var/file*.txt
核心知识点:
- xargs 默认将参数传递到命令末尾,cp 的参数顺序是" cp 源 目标",需要使用占位符来控制参数位置
- 占位符可以自定义任意字符
2.4.3.3 -print0 + xargs -0 安全处理带特殊字符文件名,生产推荐
# 准备测试环境
mkdir dir3
touch dir3/file{1..10}.txt
# 创建一个带空格的文件
touch dir3/"file test.txt"
ls dir3
# 带空格文件被拆分为2个文件,报错
find dir3 -name "*.txt" | xargs ls -l
# 解决方法一: 使用占位符替换
find dir3 -name "*.txt" | xargs -I {} ls -l {}
# 解决方法二: 使用 -print0 改变默认动作-print,使用空字符 \0 而不是换行符作为分隔符,使用 xargs -0 按空字符 \0 解析输入
find dir3 -name "*.txt" -print0 | xargs -0 ls -l
核心知识点:
- -print0 改变默认动作-print,使用空字符 \0 而不是换行符作为分隔符
- xargs -0 按空字符 \0 解析输入
- 完美处理空格,换行符,引号等特殊字符
- 生产环境推荐
2.5 locate 通过数据库查找文件
根据数据库文件(/var/lib/locatedb)查找,查询速度快
# Ubuntu默认不带该软件,如需使用手动安装
sudo apt install plocate -y
updatedb # 更新数据库文件,系统默认每天更新一次
locate 字符 # 查找包含指定字符的文件
locate -i 字符 # 不区分大小写
locate -r # 使用正则表达式搜索
locate -n N # 只列举前N个匹配项目
三、总结正则表达式的用法
3.1 grep
常用的文本搜索命令,用于在 文件 或 命令输出 中查找匹配 指定模式 的行
命令格式: grep [选项] 模式 [文件...]
3.1.1 常用选项
grep --help
| 选项 | 说明 |
|---|---|
-i | 忽略大小写 |
-v | 反向匹配,排除不想要的行 |
-n | 显示行号 |
-c | 统计匹配行数 |
-r | 递归搜索目录 |
-E | 使用正则表达式(推荐) |
-o | 只显示匹配的部分 |
-C n | 显示匹配行及前后 n 行 |
-B n | 显示匹配行及前 n 行 |
-A n | 显示匹配行及后 n 行 |
3.1.2 示例
# 准备测试文件
cp /etc/passwd grep.txt
# -i 忽略大小写
grep -i root grep.txt
# -n 显示行号
grep -in root grep.txt
# -v 反向匹配
grep -vn root grep.txt
# -c 统计行号
grep -ic root grep.txt
# -o 仅显示匹配的部分
grep -ino root grep.txt
# -C 2 显示匹配行及前后2行
grep -in -C 2 root grep.txt
# -B 1 显示匹配行及前1行
grep -in -B 1 bash grep.txt
# -A 1 显示匹配行及后1行
grep -in -A 1 root grep.txt
3.2 正则表达式
3.2.1 什么是正则表达式
一套匹配文本的高级搜索规则,用于模糊匹配,批量匹配
2种规则:
- 元字符: 决定需要匹配什么字符
- 量词: 决定需要匹配的字符出现多少次
3.2.2 基本正则 和 扩展正则
基本正则特殊字符需要加反斜杠 \ 转义
| 类型 | 命令 | 量词写法 | 或 / 分组写法 |
|---|---|---|---|
| 基本正则 | grep | \{n\},\{n,\} | |,\(\) |
| 扩展正则 | grep -E 或 egrep | {n},{n,} | |,() |
建议使用 grep -E ,不用转义,少出错
3.2.3 基本元字符
| 元字符 | 含义 | 示例 |
|---|---|---|
. | 匹配任意 单个 字符 | r..t 匹配 root,r00t,r@#t |
^ | 匹配行首 | ^root 匹配以 root 开头的行 |
$ | 匹配行尾 | bash$ 匹配以 bash 结尾的行 |
[] | 匹配方括号中任意一个字符 | [0-9] 匹配任意数字,[a-z] 小写字母,[A-Z] 大写字母 |
[^] | 匹配不在方括号中的字符 | [^0-9] 匹配非数字 |
\ | 转义,把后一个特殊字符转义为普通字符 | \. 匹配 . 本身 |
# 匹配单个字符
grep 'r..t' grep.txt
# 匹配行首
grep '^root' grep.txt
# 匹配行尾
grep 'bash$' grep.txt
# [] 字符集合
grep 'r[a-z][a-z]t' grep.txt
3.2.4 量词
需要使用 grep -E
| 量词 | 含义 |
|---|---|
* | 前导字符出现 0 次或 多次 |
+ | 前导字符出现 1次 或 多次 |
? | 前导字符出现 0次 或 1次 |
{n} | 恰好出现 n次 |
{n,} | 至少出现 n次 |
{n,m} | 出现 n 到 m 次 |
# * 0次或多次, r | ro | roo 等都匹配
grep 'ro*' grep.txt
# + 1次或多次,需要使用扩展正则-E, ro | roo 等匹配
grep -E 'ro+' grep.txt
# {n} 精确次数,需要使用扩展正则-E
grep -E 'ro{2}' grep.txt
3.2.5 扩展正则特有规则
需要使用 grep -E
| 元字符 | 含义 | 示例 |
|---|---|---|
| ` | ` | 或 |
() | 分组,把多个字符作为一个整体 | (oo)+ |
\b | 单词边界 | \root\b |
# | 或
grep -E 'www-data|apache' /etc/passwd
# () 分组
grep -E 'r(oo)+' /etc/passwd
# \b 单词边界
grep -E '\root\b' /etc/passwd
3.3 grep 使用 正则 实战
3.3.1 查看配置文件有效配置行
# 查看 nginx 配置( \s表示任意空白字符(包括空格,Tab),过滤所有注释行和空白行 )
grep -Ev '^\s*#|^\s*$' /etc/nginx/nginx.conf
# 查看 SSH 有效配置
grep -vE '^#|^$' /etc/ssh/sshd_config
3.3.2 统计访问日志中的状态码
grep -oE '[0-9]{3}' /var/log/nginx/access.log | sort | uniq -c
四、根据课程完成综合实战相关练习
grep 和 find 命令实战案例: 日志分析
# 过滤日志目录下近 7天 修改过的文件中包含指定关键字的行
find /var/log/ -type f -mtime -7 | xargs grep -iE "error|failed"
# 文件名有特殊字符使用
find /var/log/ -type f -mtime -7 | xargs -I {} grep -iE "error|failed" {}
# -n 显示行号
find /var/log/ -type f -mtime -7 | xargs grep -inE "error|failed"
# 查看前 10 行
find /var/log/ -type f -mtime -7 | xargs grep -iE "error|failed" | head -10
# 统计每个文件出现指定关键字的行数
find /var/log/ -type f -mtime -7 | xargs grep -icE "error|failed"
# 使用 Shell 脚本生成报告
cat > /root/gen_report.sh << 'EOF'
#!/bin/bash
REPORT="/root/error_report.txt"
echo "日志错误摘要报告" > $REPORT
echo "生成时间: $(date)" >> $REPORT
echo "========================================" >> $REPORT
echo "" >> $REPORT
echo "【各文件错误次数统计】" >> $REPORT
find /var/log -type f -mtime -7 2>/dev/null | xargs grep -icE "error|failed" >> $REPORT
echo "" >> $REPORT
echo "【前 10 条错误详情(含文件名、行号)】" >> $REPORT
find /var/log -type f -mtime -7 2>/dev/null | xargs grep -inE "error|failed" | head -10 >> $REPORT
echo "" >> $REPORT
echo "========================================" >> $REPORT
echo ""
echo "报告已生成: $REPORT"
EOF
# 运行测试脚本
bash /root/gen_report.sh
# 查看生成日志报告
cat /root/error_report.txt
五、完成存储管理的命令总结
二、使用 parted 管理分区
2.1 parted 交互模式分区
2.1.1 查看分区表
# 查看分区表
parted /dev/sda
print
# 退出
quit 或 Ctrl + D
# 新添加磁盘查看分区表报错未识别磁盘标签
parted /dev/sdb
print
2.1.2 创建 GPT 分区表
# 写入 GPT 磁盘标签
mklabel gpt
# 查看分区表
print
2.1.3 创建分区
# 创建首个分区
mkpart #输入命令开始交互式分区
Partition name? []? date # 输入分区名称
File system type? [ext2]? xfs # 标记文件系统类型,不实际格式化
Start? 2048s # 分区起始位置(首个分区从2048扇区开始,确保对齐)
End? 10G # 分区结束位置
# 创建第二个分区
mkpart
Partition name? []? logs
File system type? [ext2]? xfs
Start? 10G # 起始位置从上一个分区结束位置开始
End? 20G
# 查看分区
print
# 退出
q 或 Ctrl + D
# 向内核注册分区信息
udevadm settle
2.1.4 删除分区
# 进入指定磁盘进行交互操作
parted /dev/sdb
print
# 删除分区 2
rm 2
print
# 删除分区 1
rm 1
print
# 退出
q
# 向内核注册分区信息
udevadm settle
2.2 parted 非交互模式分区
# 创建 GPT 分区表,已有分区表会提示是否覆盖
parted /dev/sdb mklabel gpt
# 创建分区
parted /dev/sdb mkpart data xfs 2048s 10G
parted /dev/sdb mkpart logs xfs 10G 20G
# 查看分区表信息
parted /dev/sdb print
# 向内核注册分区信息
udevadm settle
# 删除分区表
parted /dev/sdb rm 1
parted /dev/sdb rm 2
# 查看分区表信息
parted /dev/sdb print
# 向内核注册分区信息
udevadm settle
2.3 查看分区信息
# 查看分区信息
lsblk /dev/sdb
# 带文件系统查看,未创建文件系统内容显示为空
lsblk --fs /dev/sdb
# 查看 UUID 和 文件系统类型,挂载使用
blkid /dev/sdb1
# 查看分区表信息
parted /dev/sdb print
三、创建文件系统
3.1 常见文件系统
- XFS: RHEL 默认和推荐文件系统
- EXT4: Ubuntu 默认,通用文件系统
- 其他: FAT32、NTFS等
3.2 XFS 文件系统
# 创建 XFS 文件系统
mkfs.xfs /dev/sdb1
# 带文件系统查看,未创建文件系统内容显示为空
lsblk --fs /dev/sdb
3.3 EXT4 文件系统
# 创建 EXT4 文件系统
mkfs.ext4 /dev/sdb2
# 带文件系统查看,未创建文件系统内容显示为空
lsblk --fs /dev/sdb
3.4 文件系统选择建议
文件系统对比
| 特性 | XFS | EXT4 | FAT32 / exFAT |
|---|---|---|---|
| 单个文件最大大小 | 8 EB | 16 TB | 4 GB / 16 EB |
| 单个分区最大大小 | 8 EB | 1 EB | 2 TB / 128 PB |
| 在线缩减 | 不支持 | 支持 | 不支持 |
| 默认文件系统 | RHEL | Ubuntu | 数据交换 |
选择建议
| 场景 | 文件系统 | 说明 |
|---|---|---|
| 数据库服务器 | XFS | 大文件、高并发性能优异 |
| 媒体服务器 | XFS | 大文件顺序读写性能高 |
| 通用Web服务器 | XFS / EXT4 | 根据系统选择,Rocky XFS,Ubuntu EXT4 |
| 邮件服务器 | XFS | 大量小文件,XFS的B+树管理更高效 |
| 桌面/个人电脑 | EXT4 | |
| 嵌入式系统 | EXT4 | |
| 跨平台数据交换 | exFAT | Windows / macOS / Linux 全兼容 |
| U盘 / 移动硬盘 | exFAT | 全平台支持 |
四、挂载文件系统
本质是把一个 文件系统(分区) 和一个 目录 关联起来
文件系统(分区) 是 创建了文件系统的 块设备文件
目录 称为 挂载点 ,该目录为访问 分区 的入口
4.1 mount 临时挂载
# 创建挂载点
mkdir /mnt/data /mnt/logs
# 临时挂载
mount /dev/sdb1 /mnt/data/
mount /dev/sdb2 /mnt/logs/
# 查看挂载情况
mount | grep sdb
df -Th
df -Th /mnt/data/
df -Th /mnt/logs/
# 取消挂载,可以使用 挂载点,也可以使用 文件系统(分区)名
umount /mnt/data
umount /dev/sdb2
4.2 /etc/fstab 永久挂载
# 获取设备 UUID
blkid /dev/sdb*
lsblk --fs /dev/sdb
# 编辑 /etc/fstab 文件,在最下方添加挂载规则,defaults为默认挂载选项
vim /etc/fstab
UUID="899b11ec-0d0f-472d-b6c1-6b0a786d7c40" /mnt/data xfs defaults 0 0
UUID="e1104ffe-66b6-496d-85f9-ccfa5a852f23" /mnt/logs auto defaults 0 0
# 重新加载systemd并挂载所有
systemctl daemon-reload
mount -a
# 验证
mount | grep sdb
df -Th
# 取消挂载,编辑 /etc/fstab 文件,删除对应挂载规则,并重启加载挂载规则
vim /etc/fstab
systemctl daemon-reload
mount -a
4.3 常见挂载选项
| 选项 | 含义 | 说明 |
|---|---|---|
defaults | 默认选项集 | 相当于 rw,suid,dev,exec,auto,nouser,async 这些选项 |
rw / ro | 读写 / 只读 | 控制文件系统访问模式 |
exec / noexec | 允许 / 禁止执行二进制文件 | noexec 可提高安全性 |
auto / noauto | 自动 / 手动挂载 | 控制 mount -a 是否挂载 |
remount | 在线重新挂载 | 不卸载即可改变选项 |
nofail | ||
_netdev | ||
x-systemd | ||
automount |
本地硬盘挂载选项: defaults,nofail
网络磁盘挂载选项: defaults,_netdev,x-systemd,automount,(nofail)
# 临时挂载使用挂载选项
mount -o ro,noexec /dev/sdb1 /mnt/data
# 临时挂载在线切换为读写
mount -o remount,rw /mnt/data
# 永久挂载规则配置自定义选项
vim /etc/fstab
UUID="899b11ec-0d0f-472d-b6c1-6b0a786d7c40" /mnt/data xfs ro,noexec 0 0
# 查看挂载选项,输出结果 () 中内容即为挂载选项
mount | grep data
# 输出结果 OPTIONS 列即为挂载选项
findmnt /mnt/data
五、Swap 交换分区
5.1 交换分区概述
使用硬盘作为虚拟内存
- 物理内存不足时,将不活跃的内存页写入交换分区
- 防止 OOM (Out Of Memory) 导致进程被内核杀死
- 速度远低于内存
建议容量: 物理内存 大于8G 时,交换分区至少 4G
5.2 查看当前 Swap
# 查看 物理内存 和 Swap 使用情况
free -h
# 查看 Swap 详细信息,包括多个 Swap 的优先级
swapon --show
# Ubuntu 和 Rocky 交换分区类型分别是 文件 和 分区 ,类型不同,但效果一致
5.3 创建 Swap 分区
# Rocky
# 创建分区
parted /dev/sdc mklabel gpt
parted /dev/sdc mkpart swap1 linux-swap 2048s 1G
udevadm settle
# 查看分区
lsblk /dev/sdc
# 创建 交换分区 文件系统
mkswap /dev/sdc1
# 临时挂载 交换分区
swapon /dev/sdc1
# 查看 Swap 详细信息
swapon --show
# 永久挂载 交换分区
# 获取 交换分区 UUID 并追加写入 /etc/fstab 文件
blkid /dev/sdc1
echo 'UUID="0c363611-0841-445c-9cdf-e4331b50e328" swap swap default 0 0' >> /etc/fstab
# 重载配置并激活 /etc/fstab 文件中的 交换分区
systemctl daemon-reload
swapon -a
# 查看 Swap 详细信息
swapon --show
# 临时停用指定 交换分区
swapoff /dev/sdc1
# 永久停用指定 交换分区 , 注释 或 删除 指定 交换分区 挂载规则
vim /etc/fstab
# UUID="0c363611-0841-445c-9cdf-e4331b50e328" swap swap default 0 0
# 重载配置并激活 /etc/fstab 文件中的 交换分区
systemctl daemon-reload
swapon -a
# 查看 Swap 详细信息
swapon --show
5.4 创建 Swap 文件
# Ubuntu
# 创建大文件
dd if=/dev/zero of=/swapfile bs=1G count=2
# 设置文件权限
chmod 600 /swapfile
# 设置文件系统为 Swap
mkswap /swapfile
# 临时激活
swapon /swapfile
# 永久激活 交换分区
echo '/swapfile none swap sw 0 0' >> /etc/fstab
systemctl daemon-reload
swapon -a
# 查看 Swap 详细信息
swapon --show
5.5 创建 Swap 逻辑卷
5.6 调整 Swap 优先级
# 在 /etc/fstab 中使用 pri 选项设置优先级 (数字越大优先级越高)
/swapfile none swap sw,pri=20 0 0
/swap.img none swap sw,pri=10 0 0
# 卸载所有 Swap 并重新挂载使配置生效
swapoff -a
swapon -a
# 查看优先级
swapon --show
六、完成LVM的命令总结和课程演示练习
6.1 LVM 概述
在 物理磁盘 和 文件系统 之间添加一个抽象层,提供更灵活的磁盘管理,比如在线扩容,镜像,快照
有一定性能损失
LVM 使用工作流程:
物理磁盘 → 物理卷(PV) → 卷组(VG) → 逻辑卷(LV) → 文件系统 → 挂载使用
6.2 LVM 逻辑卷管理完整流程
6.2.1 准备物理设备
# 使用 parted 创建分区
parted -s /dev/sdd mklabel gpt mkpart primary 0% 100% set 1 lvm on
parted -s /dev/sde mklabel gpt mkpart primary 0% 100% set 1 lvm on
parted -s /dev/sdf mklabel gpt mkpart primary 0% 100% set 1 lvm on
# 向内核注册分区信息
udevadm settle
# 查看分区
lsblk /dev/sdd /dev/sde /dev/sdf
6.2.2 创建物理卷 (PV)
# 创建 PV
pvcreate /dev/sdd1 /dev/sde1 /dev/sdf1
# 查看 PV
pvs
pvscan
# 查看所有 PV 详细信息
pvdisplay
# 查看指定 PV 详细信息
pvdisplay /dev/sdd1 /dev/sde1 /dev/sdf1
6.2.3 创建卷组 (VG)
# 创建 VG
vgcreate vg_data /dev/sdd1 /dev/sde1 /dev/sdf1
# 查看 VG
vgs
vgscan
# 查看所有 VG 详细信息
vgdisplay
# 查看指定 VG 详细信息
vgdisplay vg_data
6.2.4 创建逻辑卷 (LV)
# 创建 LV
lvcreate -n lv_data -L 10G vg_data
lvcreate -n lv_logs -L 20G vg_data
# 查看 LV
lvs
lvscan
# 查看所有 LV 详细信息
lvdisplay
# 查看指定 LV 详细信息
lvdisplay /dev/vg_data/lv_data /dev/vg_data/lv_logs
6.2.5 创建文件系统并挂载
# 创建文件系统
mkfs.xfs /dev/vg_data/lv_data
mkfs.ext4 /dev/vg_data/lv_logs
# 创建挂载点
mkdir -pv /opt/ruoyi/logs
# 永久挂载
echo '/dev/vg_data/lv_data /opt/ruoyi xfs defaults 0 0' >> /etc/fstab
echo '/dev/vg_data/lv_logs /opt/ruoyi/logs ext4 defaults 0 0' >> /etc/fstab
systemctl daemon-reload
mount -a
# 验证
df -Th
6.3 逻辑卷 (LV) 扩容
# 检查 VG 是否有可用空间
vgs vg_data
# 扩容方法一: 推荐,一步完成 LV 和 FS 扩展
lvextend -r -L +5G /dev/vg_data/lv_data
# 验证并查看文件系统类型
df -Th /dev/vg_data/lv_data
# 扩容方法二: 扩展 LV (不使用 -r), 2 种方法 , 指定 LV 总容量 或 给指定 LV 增加多少容量
lvextend -L 20G /dev/vg_data/lv_data
lvextend -L +5G /dev/vg_data/lv_logs
# 扩展 FS
# XFS 文件系统扩展方法,使用挂载点
xfs_growfs /opt/ruoyi
# EXT4 文件系统扩展方法,使用设备名
resize2fs /dev/vg_data/lv_logs
# 验证
df -Th /dev/vg_data/lv_data /dev/vg_data/lv_logs
6.4 卷组 (VG) 扩容
VG 空间不足,添加新硬盘
# 使用 parted 创建分区
parted -s /dev/sdg mklabel gpt mkpart primary 0% 100% set 1 lvm on
# 向内核注册分区信息
udevadm settle
# 查看分区
lsblk /dev/sdg
# 创建 PV
pvcreate /dev/sdg1
# 扩展 VG
vgextend vg_data /dev/sdg1
# 查看 VG 可用空间
vgs vg_data
# 后续可继续给 LV 扩容
6.5 从 卷组 (VG) 移除 物理卷 (PV)
6.5.1 PV 未被使用,直接移除
# 查看 PV 使用情况, PFree 显示 0 表示全部已使用,PSize = PFree 表示完全未使用
pvs
# 从 VG 中 移除未使用的 PV
vgreduce vg_data /dev/sdg1
# 删除 PV 元数据
pvremove /dev/sdg1
# 验证
pvs
6.5.2 PV 已被使用,需要迁移数据后移除
# 查看 PV 使用情况
pvs
# 将需要移除的 PV /dev/sdd1 上的数据自动迁移到其他 PV
pvmove /dev/sdd1
# 也可指定迁移到指定 PV
pvmove /dev/sdd1 /dev/sdg1
# 验证数据已迁移,PSize = PFree 表示完全未使用
pvs
# 从 VG 中 移除未使用的 PV
vgreduce vg_data /dev/sdd1
# 删除 PV 元数据
pvremove /dev/sdd1
# 验证
pvs
6.6 删除 LVM 组件
操作不可逆,操作前备份数据
# 备份数据
rsync -av /opt/ruoyi/ /backup/ruoyi_backup/
# 卸载文件系统
umount /opt/ruoyi/logs
umount /opt/ruoyi
# 删除或注释持久挂载规则
vim /etc/fstab
# /dev/vg_data/lv_data /opt/ruoyi xfs defaults 0 0
# /dev/vg_data/lv_logs /opt/ruoyi/logs ext4 defaults 0 0
# 重载 systemctl
systemctl daemon-reload
# 删除逻辑卷 LV
lvremove /dev/vg_data/lv_data
lvremove /dev/vg_data/lv_logs
# 删除卷组 VG
vgremove vg_data
# 删除物理卷 PV
pvremove /dev/sde1 /dev/sdf1 /dev/sdg1
# 验证
lvs
vgs
pvs
七、总结linux系统的启动过程
1.1 Linux 启动流程
| 启动流程 | 阶段 | 组件 | 作用 |
|---|---|---|---|
| 1 | 硬件初始化 | BIOS / UEFI | 固件层,负责硬件自检(POST),检查CPU、内存、硬盘等硬件是否正常;然后根据启动顺序选择引导设备(硬盘、U盘、网络等),将控制权交给GRUB2 |
| 2 | 引导程序 | GRUB2 | 引导加载选中的内核(vmlinuz)和initramfs到内存,并向内核传递启动参数(运行级别),将控制器交给内核 |
| 3 | 内核初始化 | Kernel | 负责检测并加载硬件驱动、进程调度、内存管理、文件系统管理等核心功能,是系统运行的基础;挂载initramfs为临时根文件系统,启动systemd进程(PID 1) |
| 4 | 临时根文件系统 | initramfs | 包含存储设备驱动(SATA、NVME)、文件系统模块(ext4、xfs)、LVM/RAID等工具,负责在挂载真正的根文件系统前加载必要的驱动,确保内核能够识别并挂载根文件系统 |
| 5 | 系统初始化 | systemd | PID 1 进程,系统和服务管理器,负责挂载真正的根文件系统、并行启动所有系统服务、进入默认target |
1.2 启动流程相关文件
| 文件 | Rocky 10 | Ubuntu 24.04 |
|---|---|---|
| 内核文件 | /boot/vmlinuz-* | /boot/vmlinuz-* |
| initramfs 镜像 | /boot/initramfs-*.img | /boot/initrd.img-* |
| GRUB 配置文件 | /boot/grub2/grub.cfg | /boot/grub/grub.cfg |
| GRUB 默认配置 | /etc/default/grub | /etc/default/grub |
| 默认target 链接 | /etc/systemd/system/default.target | /usr/lib/systemd/system/default.target |
八、动手制作一个systemd的unit文件
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
After=network.target syslog.target
[Service]
User=mysql
Group=mysql
Type=notify
ExecStart=/usr/local/mysql/bin/mysqld --defaults-file=/etc/my.cnf
ExecStop=/usr/local/mysql/bin/mysqladmin -u root shutdown
LimitNOFILE=65535
Restart=on-failure
RestartSec=3
[Install]
WantedBy=multi-user.target
九、完成每日凌晨1点定时打包/var/log/message文件的定时任务
# 创建备份目录
mkdir /backup
# Rocky 最小安装安装 tar gzip
dnf install -y tar gzip
# 创建备份脚本
cat > /backup/timer_logs_message_backup.sh << 'EOF'
#!/bin/bash
BACKUP_DIR=/backup
BACKUP_FILE=message-timer-$(date +%F).tar.gz
# 检查目录,不存在则创建
if [ ! -d $BACKUP_DIR ];then
mkdir $BACKUP_DIR
fi
# 备份 message 日志
/usr/bin/tar czf $BACKUP_DIR/$BACKUP_FILE /var/log/message 2>/dev/null
# 清除超过一周的备份文件
find $BACKUP_DIR -name *.tar.gz -mtime +7 | xargs -I {} rm -rf {}
EOF
# 添加执行权限
chmod +x /backup/timer_logs_message_backup.sh
# 测试脚本执行
/backup/timer_logs_message_backup.sh
ll /backup/
# 创建 Service 单元,Type=oneshot 表示执行一次退出
cat > /etc/systemd/system/backup_logs_message.service << 'EOF'
[Unit]
Description=Log Backup Service (Timer)
[Service]
Type=oneshot
ExecStart=/backup/timer_logs_message_backup.sh
User=root
EOF
# 创建 Timer 单元,与 Service 单元同名,Persistent=true 表示错过执行补偿,例如指定时间系统关机,开机后立即补执行
cat > /etc/systemd/system/backup_logs_message.timer << 'EOF'
[Unit]
Description=Log Backup Timer
[Timer]
OnCalendar=*-*-* 01:00:00
Persistent=true
[Install]
WantedBy=timers.target
EOF
# 启动 Timer
systemctl daemon-reload
systemctl enable --now backup_logs_message.timer
# 验证
# 查看所有 Timer
systemctl list-timers
# 手动触发执行,需要确保 SELinux 关闭
systemctl start backup_logs_message.service
ls -l /backup
# 查看日志
journalctl -u backup_logs_message.service -n 20
十、完成每半小时自动创建一个文件并且删除完成日志记录的定时任务
# 创建目录
mkdir /var/log/touch_logs
# 创建脚本
cat > /var/log/touch_logs/timer_touch_flag.sh << 'EOF'
#!/bin/bash
TOUCH_DIR=/var/log/touch_logs
TOUCH_FILE=$(date +%Y%m%d_%H%M%S).flag
# 检查目录,不存在则创建
if [ ! -d $BACKUP_DIR ];then
mkdir $BACKUP_DIR
fi
# 创建一个文件
/usr/bin/touch $TOUCH_DIR/$TOUCH_FILE 2>/dev/null
# 清除超过一周的文件
find $TOUCH_DIR -name "*.flag" -mtime +7 | xargs -I {} rm -rf {}
EOF
# 添加执行权限
chmod +x /var/log/touch_logs/timer_touch_flag.sh
# 测试脚本执行
/var/log/touch_logs/timer_touch_flag.sh
ll /var/log/touch_logs
# 创建 Service 单元,Type=oneshot 表示执行一次退出
cat > /etc/systemd/system/touch_flag.service << 'EOF'
[Unit]
Description=Log Backup Service (Timer)
[Service]
Type=oneshot
ExecStart=/var/log/touch_logs/timer_touch_flag.sh
User=root
EOF
# 创建 Timer 单元,与 Service 单元同名,Persistent=true 表示错过执行补偿,例如指定时间系统关机,开机后立即补执行
cat > /etc/systemd/system/touch_flag.timer << 'EOF'
[Unit]
Description=Log Backup Timer
[Timer]
OnCalendar=*-*-* *:00,30:00
Persistent=true
[Install]
WantedBy=timers.target
EOF
# 启动 Timer
systemctl daemon-reload
systemctl enable --now touch_flag.timer
# 验证
# 查看所有 Timer
systemctl list-timers
# 手动触发执行,需要确保 SELinux 关闭
systemctl start touch_flag.service
ls -l /var/log/touch_logs
# 查看日志
journalctl -u touch_flag.service -n 20

922

被折叠的 条评论
为什么被折叠?



