Linux 作为一款开源、稳定且安全的操作系统,广泛应用于服务器、嵌入式设备及个人计算机领域。对于初学者而言,掌握其基本操作逻辑与常用命令是入门的核心。

一、Linux 常用命令

在 Linux 系统中,man 命令是查看命令帮助文档的主要工具,它可以显示命令的详细说明、参数选项、使用示例等信息。

使用 man 查看 Linux 常用命令的基本格式非常简单:

man [命令名称]

# 查看 grep 命令的帮助
man grep

man 页面中,可以使用以下操作进行浏览:

  • Enter 键或向下箭头:逐行滚动
  • 按空格键:向下翻一页
  • b 键:向上翻一页
  • / 键后输入关键词:搜索关键词
  • n 键:跳转到下一个搜索结果
  • q 键:退出 man 页面

1.1 目录与文件管理

功能 命令 示例
切换目录 cd cd /home(绝对路径)cd ..(上一级)cd ~(当前用户主目录)
查看目录内容 ls ls -l(长格式)ls -a(显示隐藏文件)ls -lh(人类可读大小)
创建文件 touch touch test.txt touch /tmp/note.md
创建目录 mkdir mkdir docs mkdir -p docs/linux(递归创建)
删除 rm rm test.txt(删文件)rm -r docs(删目录)rm -rf old_dir(强制删目录)
复制 cp cp test.txt /home(复制文件)cp -r docs /tmp(复制目录)
移动 / 重命名 mv mv test.txt demo.txt(重命名)mv demo.txt /home(移动)

1.1.1 Linux 文件属性

1. 查看文件属性:ls -l

核心命令,输出包含文件类型、权限、所有者、大小等关键属性。

# 示例:查看当前目录文件属性
ls -l
# 输出格式(逐字段解析):
# -rwxr-xr-- 1 user1 group1 1234 Aug 10 14:30 test.sh
输出字段 含义说明 示例值
-rwxr-xr-- 文件类型 + 权限 普通文件 + 权限
1 硬链接数 1 个硬链接
user1 所有者(属主) 用户 user1
group1 所属组(属组) 组 group1
1234 文件大小(字节) 1234 字节
Aug 10 14:30 最后修改时间 8 月 10 日 14:30
test.sh 文件名 / 目录名 文件 test.sh

2. 核心属性解析

ls -l 输出首字符标识文件类型,常见类型:

# 示例:不同类型文件的首字符
ls -l
# d :目录(如 drwxr-xr-x)
# - :普通文件(如 -rwxr-xr--)
# l :软链接(如 lrwxrwxrwx)
# b :块设备(如 /dev/sda)
# c :字符设备(如 /dev/tty)
首字符 类型 常见场景
d 目录 /home、/etc
- 普通文件 .txt、.sh、日志文件
l 软链接 快捷方式(如 ln -s 源 目标)
b/c 设备文件 硬盘、终端设备

权限分 3 组,对应「所有者(u)、所属组(g)、其他用户(o)」,每组含 r(读)、w(写)、x(执行):

# 示例:权限字段拆解(-rwxr-xr--)
# 所有者(u):rwx → 读+写+执行
# 所属组(g):r-x → 读+执行
# 其他(o):r-- → 仅读
权限字符 数字值 功能说明
r 4 读(查看内容,如 cat)
w 2 写(修改内容,如 vim)
x 1 执行(运行脚本 / 进入目录)
- 0 无该权限

3. 修改文件属性

3.1 修改权限:chmod
\# 方法1:符号法(u/g/o/a + r/w/x)

chmod u+x test.sh   # 给所有者加执行权

chmod g-w test.sh   # 给所属组删写权

chmod a+r test.sh   # 给所有用户加读权

\# 方法2:数字法(3位数字,对应 u/g/o)

chmod 754 test.sh   # u=rwx(7)、g=r-x(5)、o=r--(4)

chmod 777 file.txt  # 所有用户读+写+执行(慎用)
3.2 修改所有者:chown
# 格式:chown 新属主:新属组 文件名
chown user2 test.sh       # 仅改属主为user2
chown user2:group2 test.sh# 改属主为user2、属组为group2
3.3 修改所属组:chgrp
# 格式:chgrp 新属组 文件名
chgrp group3 test.sh      # 改属组为group3# 格式:chgrp 新属组 文件名

4. 常用辅助命令

# 查看文件详细属性(含inode)
stat test.sh

# 查看当前用户所属组
groups

# 以人类可读格式显示大小(配合ls)
ls -lh test.sh

1.2 文件内容查看

功能 命令 示例
完整查看 cat cat /etc/hostname cat -n test.txt(显示行号)
分页查看 less less /var/log/syslog(按 q退出,/搜索)
查看开头 head head -5 /etc/passwd(前 5 行)
查看结尾 / 实时日志 tail tail -10 log.txt(后 10 行)tail -f /var/log/nginx.log(实时跟踪)

1.3 网络命令

1.3.1 网络状态查看

功能 命令 示例
查看 IP / 网卡信息 ifconfig/ip addr ifconfig eth0(查看 eth0 网卡)ip addr show(全网卡信息)
查看路由表 route/ip route route -n(数字显示网关)ip route list(查看路由)
查看网络连接 netstat/ss netstat -tuln(监听端口:t=TCP,u=UDP,l = 监听,n = 数字)ss -tulnp(显示进程名,需 root)
查看 DNS 配置 cat /etc/resolv.conf cat /etc/resolv.conf(显示 DNS 服务器)

1.3.2 网络测试与连接

功能 命令 示例
测试主机连通性 ping ping baidu.com(默认 ICMP,Ctrl+C 停止)ping -c 4 baidu.com(仅发 4 个包)
测试端口连通性 telnet/nc telnet baidu.com 80(测试 80 端口)nc -zv baidu.com 80(z = 扫描,v = 详细)
跟踪路由路径 traceroute/mtr traceroute baidu.com(跟踪跳转节点)mtr baidu.com(实时路由监控)
发送 HTTP 请求 curl/wget curl baidu.com(获取页面内容)curl -I baidu.com(仅看响应头)wget https://xxx.com/file.zip(下载文件)

1.3.3 网络配置(临时生效)

功能 命令 示例
启用 / 禁用网卡 ifconfig/ip link ifconfig eth0 up(启用 eth0)ip link set eth0 down(禁用 eth0)
临时设 IP ifconfig/ip addr ifconfig eth0 192.168.1.100 netmask 255.255.255.0 ip addr add 192.168.1.100/24 dev eth0
临时设网关 route/ip route route add default gw 192.168.1.1 ip route add default via 192.168.1.1
临时设 DNS echo "nameserver 8.8.8.8" >> /etc/resolv.conf echo "nameserver 8.8.8.8" >> /etc/resolv.conf(添加谷歌 DNS)

1.3.4 其他实用命令

功能 命令 示例
查看网卡流量 iftop iftop -i eth0(实时监控 eth0 流量,需安装)
扫描局域网设备 arp-scan arp-scan -l(扫描当前网段设备,需 root + 安装)
查看网络日志 dmesg/journalctl `dmesg

1.3.5 curl 命令

curl 是 Linux 下功能强大的命令行工具,支持多种 HTTP 请求方法,广泛用于接口测试、数据传输和网页爬取。以下表格系统整理了常用 HTTP 方法的 curl 用法、核心参数、适用场景及示例,方便对比和快速查阅。

HTTP 方法 核心参数 作用说明 典型使用场景 完整示例
GET 默认(无需额外参数) 从服务器获取资源,请求参数通常拼接在 URL 中,不适合传输敏感数据(参数暴露在 URL) 1. 访问网页 / 接口获取数据2. 传递少量非敏感参数(如分页、查询关键词) 1. 简单获取网页:curl https://www.example.com2. 带参数获取数据(分页查询第 2 页):curl "https://api.example.com/users?page=2&size=10"
POST -X POST(指定方法)+ 数据参数(如 -d/-F 向服务器提交数据(请求体携带数据),适合传输表单、JSON、文件等,参数不暴露 1. 提交表单(登录、注册)2. 上传 JSON 格式数据(API 接口)3. 上传文件(图片、文档) 1. 提交表单数据(登录):curl -X POST -d "username=admin&password=123456" https://api.example.com/login2. 提交 JSON 数据(需指定 Content-Type):curl -X POST -H "Content-Type: application/json" -d '{"name":"test","age":20}' https://api.example.com/user3. 上传文件(图片,-F 模拟表单文件域):curl -X POST -F "avatar=@/home/user/photo.jpg" https://api.example.com/upload
PUT -X PUT 向服务器全量更新资源(需提供资源完整数据,若资源不存在则创建) 1. 完整更新用户信息(如修改姓名、年龄、邮箱)2. 替换服务器上的文件 全量更新用户信息(ID=123 的用户):curl -X PUT -H "Content-Type: application/json" -d '{"name":"newName","age":25}' https://api.example.com/user/123
PATCH -X PATCH 向服务器部分更新资源(仅需提供需修改的字段,无需完整数据) 1. 仅修改用户的邮箱(无需传姓名、年龄)2. 局部更新订单状态 部分更新用户邮箱(ID=123 的用户):curl -X PATCH -H "Content-Type: application/json" -d '{"email":"new@example.com"}' https://api.example.com/user/123
DELETE -X DELETE 向服务器删除指定资源 1. 删除用户账号2. 删除上传的文件3. 删除订单记录 删除 ID=123 的用户:curl -X DELETE https://api.example.com/user/123带参数删除(如删除指定类型的日志):curl -X DELETE "https://api.example.com/logs?type=error"
HEAD -I(或 -X HEAD,推荐 -I 仅获取服务器响应的头部信息(不返回响应体),用于检查资源状态(如是否存在、最后修改时间) 1. 检查网页是否可访问(状态码)2. 查看文件的 Content-Length(大小)3. 验证接口是否正常(仅看头部) 1. 查看网页头部信息:curl -I https://www.example.com2. 查看接口响应头部(验证是否返回 401 未授权):curl -I https://api.example.com/private/data
OPTIONS -X OPTIONS 向服务器查询当前 URL 支持的 HTTP 方法(跨域请求中常用,获取服务器允许的请求方式) 1. 测试接口支持的方法(如是否允许 POST/PUT)2. 跨域预检请求(CORS 场景) 查询 https://api.example.com/user 支持的方法:curl -X OPTIONS -v https://api.example.com/user-v 显示详细日志,可看到响应头 Allow: GET,POST,PUT,DELETE

1.4 系统与进程

功能 命令 示例
查看系统信息 uname/cat uname -r(内核版本)cat /etc/os-release(系统版本)
查看资源 free/df free -h(内存)df -h(磁盘)
查看进程 ps ps aux(所有进程)ps aux | grep nginx(筛选 nginx 进程)
终止进程 kill kill 1234(PID 为 1234 的进程)kill -9 1234(强制终止)
查看内核环缓冲区信息 dmesg dmesg -l warn,err(显示特定级别的消息)

1.4.1 sysstat

以下是 sysstat 工具集中常用工具的命令和方法总结表格,方便快速查阅和使用:

sysstat 核心工具及常用命令表:

工具名称 主要功能 常用命令示例 命令说明
sar 系统活动全面监控(CPU、内存、网络等) sar -u 2 5 每 2 秒监控一次 CPU 使用率,共 5 次
sar -r 3 4 每 3 秒监控一次内存使用,共 4 次
sar -n DEV 1 10 每 1 秒监控一次网络接口流量,共 10 次
sar -f /var/log/sysstat/sa01 查看历史日志文件 sa01 的记录
sar -u -s 14:00 -e 15:00 查看当天 14:00-15:00 的 CPU 数据
iostat 磁盘 I/O 性能监控 iostat -x 显示所有磁盘的扩展 I/O 统计(推荐)
iostat -x sda 1 10 每 1 秒监控 sda 磁盘,共 10 次
iostat -d 2 5 每 2 秒监控一次磁盘总体 I/O,共 5 次
mpstat 多 CPU 核心监控 mpstat -P ALL 2 3 每 2 秒监控所有 CPU 核心,共 3 次
mpstat -P 0 1 5 每 1 秒监控 CPU 核心 0,共 5 次
pidstat 进程 / 线程资源监控 pidstat -u 1 5 每 1 秒监控所有进程的 CPU 使用,共 5 次
pidstat -r -p 1234 3 4 每 3 秒监控 PID=1234 的进程内存,共 4 次
pidstat -d 2 3 每 2 秒监控进程的磁盘 I/O,共 3 次
pidstat -t -p 5678 1 10 监控 PID=5678 的线程级 CPU 使用
sadf SAR 数据格式化导出 sadf -d sa01 > sar.csv 将 sa01 日志导出为 CSV 格式
sadf -g sa01 -s 08:00 -e 18:00 生成图表数据(需配合 gnuplot)

关键指标解读:

工具 核心指标 含义 预警阈值
sar/mpstat %iowait CPU 等待磁盘 I/O 的时间占比 持续 > 20% 可能存在磁盘瓶颈
%idle CPU 空闲时间占比 持续 < 10% 表示 CPU 负载高
%user/%system 用户态 / 系统态 CPU 占比 %system过高可能有内核问题
iostat %util 磁盘繁忙时间占比 持续 > 80% 表示磁盘负载过高
await I/O 请求平均等待时间(毫秒) 持续 > 10ms 需关注磁盘响应
avgqu-sz I/O 请求队列平均长度 持续 > 2 表示磁盘处理能力不足
rMB/s/wMB/s 每秒读写数据量(MB) 结合业务判断是否达到磁盘上限
pidstat %cpu 进程 CPU 使用率 单进程持续 > 90% 可能异常
rss 进程实际使用的物理内存(KB) 结合系统总内存判断是否内存泄漏
disk read/write 进程读写磁盘的字节数 识别异常读写的进程

常用场景:

监控场景 推荐工具 核心命令
系统整体负载评估 sar sar -u -r -n DEV 5 10
磁盘 I/O 瓶颈排查 iostat iostat -x 1 30
CPU 核心负载不均衡 mpstat mpstat -P ALL 1 20
定位高资源消耗进程 pidstat pidstat -u -r -d 2 15
历史性能问题复盘 sar+sadf sar -f saXXsadf -d saXX
网络流量监控 sar sar -n DEV 1 10

1.4.2 uptime

uptime 是一个在 Unix/Linux 系统中常用的命令,用于快速查看系统的运行时间以及当前系统的负载情况。

# 系统当前时间:15:30:45
# 系统已运行时长:2天3小时45分钟
# 当前登录用户数量:2个用户
# 系统平均负载:
#   - 过去1分钟:0.45
#   - 过去5分钟:0.62
#   - 过去15分钟:0.78
# (平均负载表示等待CPU处理的进程数,数值越低系统负载越轻)
15:30:45 up 2 days,  3:45,  2 users,  load average: 0.45, 0.62, 0.78

1.4.3 vmstat

vmstat(Virtual Memory Statistics,虚拟内存统计)是 Linux/Unix 系统中一款核心的系统性能监控工具,主要用于实时或周期性采集虚拟内存、进程、CPU、磁盘 I/O 等关键资源的使用状态,帮助运维或开发人员定位系统瓶颈(如内存不足、CPU 过载、I/O 阻塞等)。

vmstat 的输出分为两部分:头部摘要(仅首次采样显示,含系统基本信息)和周期性统计行(核心监控数据)。以下重点解析最常用的「默认模式」和「-a 活跃内存模式」的输出字段。

默认输出共 16 列,按「进程、内存、交换分区、IO、系统、CPU」分为 6 个维度,如下所示(以 vmstat 1 1 输出为例):

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0  98704 747684  83804 1938940    0    1    36   171   51  113  1  0 98  0  0
  1. Procs(进程状态):反映 CPU 调度压力
字段 含义 正常范围 异常说明
r 等待 CPU 调度的运行队列进程数(不含睡眠进程) 通常 ≤ CPU 核心数(如 4 核 CPU ≤4) 长期 > CPU 核心数 → CPU 资源不足,进程排队等待
b 处于不可中断睡眠状态的进程数(多为等待 I/O,如磁盘读写、网络响应) 通常 ≤1 长期 >2 → I/O 瓶颈(如磁盘慢、网络阻塞)
  1. Memory(内存状态):反映物理内存使用
字段 含义 说明
swpd 已使用的交换分区大小(单位:KB) 正常应为 0 或接近 0;若持续增长 → 物理内存不足,系统开始使用磁盘作为内存(性能大幅下降)
free 完全空闲的物理内存大小(单位:KB) 并非越大越好(空闲内存会被用于缓存),需结合 buff/cache 综合判断
buff 用于块设备缓存的内存(如磁盘分区元数据、目录缓存) 由内核管理,随磁盘 I/O 增加而增长,是正常优化
cache 用于文件内容缓存的内存(如读取的文件数据) 越大越好(减少磁盘读 I/O),内存不足时内核会自动回收
  1. Swap(交换分区):反映内存是否严重不足
字段 含义 正常范围 异常说明
si 每秒从交换分区读入物理内存的数据量(单位:KB/s) 0 持续 >0 → 物理内存不足,系统从磁盘换入数据(性能差)
so 每秒从物理内存写入交换分区的数据量(单位:KB/s) 0 持续 >0 → 内存严重不足,系统被迫将内存数据写入磁盘(紧急状态)
  1. IO(磁盘 I/O 状态):反映磁盘读写压力
字段 含义 说明
bi 每秒从块设备读入内存的数据量(单位:块 /s,1 块≈512B) 即磁盘读速率,高值表示磁盘读压力大(如数据库查询、文件读取)
bo 每秒从内存写入块设备的数据量(单位:块 /s) 即磁盘写速率,高值表示磁盘写压力大(如日志写入、数据备份)
  1. System(系统中断):反映系统内核活动
字段 含义 说明
in 每秒发生的系统中断次数(如时钟中断、I/O 中断) 数值随系统负载增长而增加,无固定标准;若突然飙升 → 可能存在硬件或驱动问题
cs 每秒发生的进程上下文切换次数(CPU 从一个进程切换到另一个) 数值与进程数正相关;若 cs 过高且 us(用户 CPU)低 → 进程切换频繁(如多线程调度不合理)
  1. CPU(CPU 使用状态):反映 CPU 资源分配
字段 含义 正常范围 异常说明
us 用户空间程序占用 CPU 的百分比(如应用、脚本) 通常 ≤70% 长期 >80% → 应用程序消耗 CPU 过高(如代码死循环、计算密集型任务未优化)
sy 内核空间占用 CPU 的百分比(如系统调用、内存管理) 通常 ≤30% 长期 >40% → 内核活动频繁(如 I/O 密集、频繁系统调用)
id CPU空闲百分比(含等待 I/O 的空闲时间) 通常 ≥20% 长期 <10% → CPU 整体过载
wa CPU 等待 I/O 完成的百分比(空闲但等待磁盘 / 网络) 通常 ≤5% 长期 >10% → I/O 瓶颈(如磁盘读写慢、网络延迟高)
st 被虚拟化 hypervisor 占用的 CPU 百分比(仅虚拟机有效) 通常 ≤1% 长期 >5% → 宿主机资源不足,影响虚拟机性能

-a 活跃内存模式 输出(更精准的内存分析):

使用 -a 选项时,memory 列组会替换为「活跃 / 非活跃内存」,更贴合现代 Linux 内存管理逻辑(区分 “正在使用” 和 “可回收” 的内存),输出示例:

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free  inact active   si   so    bi    bo   in   cs us sy id wa st
 1  0  98704 747684 1360868 1189928    0    1    35   171   51  112  1  0 98  0  0
字段 含义 说明
inact 非活跃内存(Inactive):近期未使用的内存(如关闭的应用缓存、长期未访问的文件) 内核可优先回收这部分内存给新进程,数值大不代表内存浪费
active 活跃内存(Active):正在使用或近期频繁使用的内存(如运行中应用的堆内存、频繁访问的文件缓存) 数值稳定表示内存使用合理;若持续增长 → 应用可能存在内存泄漏

1.4.4 iostat(磁盘 I/O 与 CPU 使用率监控)

iostat(Input/Output Statistics)主要用于查看 磁盘 I/O 性能CPU 使用率,尤其适合定位磁盘读写瓶颈(如磁盘响应慢、I/O 饱和等问题)。

常用参数:

参数 作用
iostat 默认输出:CPU 汇总统计 + 所有磁盘的 I/O 统计(仅一次)
iostat -d 仅输出磁盘 I/O 统计(屏蔽 CPU 信息)
iostat -x 输出扩展的磁盘 I/O 统计(包含 I/O 等待、队列长度等关键指标)
iostat 2 3 每 2 秒刷新一次,共刷新 3 次(格式:iostat [间隔秒数] [次数]
iostat -p sda 仅监控指定磁盘(如 sda,可替换为实际磁盘名,如 vdasdb

关键输出解读(以 iostat -x 2 为例):

$ iostat -x 2
Linux 5.15.0-139-generic (ubuntu)       09/16/2025      _x86_64_        (2 CPU)

avg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.75    0.50    0.44    0.03    0.00   98.28

Device            r/s     rkB/s   rrqm/s  %rrqm r_await rareq-sz     w/s     wkB/s   wrqm/s  %wrqm w_await wareq-sz     d/s     dkB/s   drqm/s  %drqm d_await dareq-sz  aqu-sz  %util
loop0            0.00      0.00     0.00   0.00    0.07     1.21    0.00      0.00     0.00   0.00    0.00     0.00    0.00      0.00     0.00   0.00    0.00     0.00    0.00   0.00
输出字段 含义
%util 磁盘繁忙率(核心指标):值越接近 100%,说明磁盘 I/O 越饱和(需警惕)
rMB/s/wMB/s 磁盘每秒读 / 写速率(单位:MB),反映实际数据传输量
await I/O 请求平均等待时间(单位:毫秒):值过高表示磁盘响应慢
avgqu-sz I/O 请求平均队列长度:长期大于 1 可能表示磁盘压力大

1.4.5 free(内存使用情况查看)

free 用于快速查看系统 物理内存(RAM)交换分区(Swap) 的使用、空闲及缓存情况,是排查内存不足的基础命令。

常用参数:

参数 作用
free 默认输出:以KB 为单位,展示内存和 Swap 基本信息
free -m MB 为单位输出(最常用,符合日常对内存大小的认知)
free -g GB 为单位输出(适合大内存服务器,如 16GB/64GB 内存)
free -h 自动选择 “人类易读” 的单位(如 2.3G、512M),无需手动指定 -m/-g
free -s 2 每 2 秒刷新一次内存数据(持续监控,按 Ctrl+C 退出)

关键输出解读(以 free -h 为例):

$ free  -h
              total        used        free      shared  buff/cache   available
Mem:          3.8Gi       1.6Gi       310Mi        15Mi       1.9Gi       1.9Gi
Swap:         923Mi        97Mi       825Mi
输出字段 含义
total 总容量:物理内存 / Swap 的总大小
used 已使用:包括进程占用、内核占用的内存(注意:缓存不算 “实际占用”)
free 完全空闲:未被任何进程或缓存使用的内存
buff/cache 缓存占用:页缓存(文件读写缓存)+ slab 缓存(内核对象缓存,可回收)
available 可用内存:free + 可回收的 buff/cache(核心指标,反映实际可分配内存)

1.4.6 top(实时系统资源监控(全能工具))

top 是 Linux 中最常用的 实时系统监控工具,可动态展示 CPU、内存、进程的资源占用情况,支持交互式操作(如排序、筛选进程),适合定位 “高资源占用进程”。

常用参数(启动时):

参数 作用
top 默认启动:每 3 秒刷新一次,展示所有进程
top -p 1234 仅监控指定 PID 的进程(如 1234,可同时指定多个:-p 1234,5678
top -u root 仅监控指定用户的进程(如 root,可替换为普通用户名,如 www
top -d 5 自定义刷新间隔为 5 秒(默认 3 秒)

交互式操作(启动后按以下按键):

按键 作用
P CPU 使用率 降序排序(默认排序,方便找 “吃 CPU” 的进程)
M 内存使用率 降序排序(方便找 “吃内存” 的进程)
T 进程运行时间 降序排序
k 杀死指定进程:按 k 后输入 PID,再按回车确认(需 root 权限)
q 退出 top 界面
1 展开显示单个 CPU 核心 的使用率(多核心服务器常用)

输出结果解读:

top - 07:21:30 up 12:05,  2 users,  load average: 0.01, 0.00, 0.00
Tasks: 301 total,   1 running, 300 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.2 sy,  0.0 ni, 99.8 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
MiB Mem :   3876.0 total,    310.5 free,   1590.0 used,   1975.5 buff/cache
MiB Swap:    923.3 total,    825.6 free,     97.6 used.   1992.9 avail Mem 

    PID USER      PR  NI    VIRT    RES    SHR S  %CPU  %MEM     TIME+ COMMAND                            
   1854 root      20   0  313316   6492   5072 S   0.3   0.2   1:36.38 vmtoolsd                           
 153004 root      20   0 1875764  34364  22860 S   0.3   0.9   0:07.65 containerd                         
      1 root      20   0  171592  13220   8604 S   0.0   0.3   0:20.08 systemd                            
输出字段 含义
load average: 0.00, 0.00, 0.00 系统负载(1/5/15 分钟平均):值接近 CPU 核心数(如 4 核为 4.0)表示负载满
%us 用户态 CPU 使用率:进程(如应用程序)占用的 CPU 比例
%sy 系统态 CPU 使用率:内核操作(如内存管理、I/O)占用的 CPU 比例
%id 空闲 CPU 使用率:值越低表示 CPU 越繁忙
%wa I/O 等待 CPU 使用率:值高表示磁盘 I/O 慢,CPU 等待 I/O 完成

1.5 用户与权限

功能 命令 示例
切换用户 su/sudo su root(切换 root)sudo apt install nginx(管理员权限执行)
修改权限 chmod chmod u+x test.sh(所有者加执行权)chmod 754 test.sh(数字法:rwxr-xr--)

1.6 常用正则规则

1.6.1 基础符号

符号 含义 示例
. 匹配任意单个字符(除换行) a.cabca1c
* 前一个字符出现 0 + 次 ab*cacabcabbbc
+ 前一个字符出现 1 + 次 ab+cabcabbbc(不匹配 ac
? 前一个字符出现 0 或 1 次 ab?cacabc(不匹配 abbc
^ 匹配行 / 字符串开头 ^abc → 匹配 abc123(不匹配 xabc
$ 匹配行 / 字符串结尾 abc$ → 匹配 123abc(不匹配 abcx
| 或运算 a|b → 匹配 ab

1.6.2 字符集

表达式 含义 示例
[abc] 匹配 a、b 或 c [ab]cacbc
[^abc] 匹配非 a、b、c 的字符 [^ab]ccc1c(不匹配 ac
[0-9] 匹配数字 [0-9]{2}1299
[a-z] 匹配小写字母 [a-z]+abcx
[A-Z] 匹配大写字母 [A-Z]AZ

1.6.3 预定义字符集

表达式 含义 等价于
\d 数字 [0-9]
\D 非数字 [^0-9]
\w 字母 / 数字 / 下划线 [a-zA-Z0-9_]
\W 非单词字符 [^a-zA-Z0-9_]
\s 空白字符(空格 / 制表符等) [ \t\n\r\f\v]
\S 非空白字符 [^ \t\n\r\f\v]

1.6.4 量词

表达式 含义 示例
{n} 恰好 n 次 a{3}aaa
{n,} 至少 n 次 a{2,}aaaaa
{n,m} n 到 m 次 a{1,3}aaaaaa

1.6.5 分组与引用

表达式 含义 示例
(abc) 分组捕获 (ab)+abab(捕获 ab
\1 引用第一个捕获组 (a)\1aa
(?:abc) 非捕获分组 (?:ab)+ → 匹配 abab但不捕获

1.6.6 常用正则规则

# 用户名:字母开头,允许字母、数字、下划线,4-16位
^[a-zA-Z][a-zA-Z0-9_]{3,15}$

# 密码:至少8位,含大小写字母、数字和特殊符号
^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{8,}$

# 邮箱地址(通用版)
^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$

# URL(支持http/https,含端口和路径)
^(https?:\/\/)?([\da-zA-Z.-]+)\.([a-zA-Z.]{2,6})([\/\w .-]*)*\/?$

# IPv4地址(含验证0-255范围)
\b((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b

# 域名(支持多级域名)
^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$

# 中国大陆手机号
^1[3-9]\d{9}$

# 中国大陆身份证号(18位,末位可能是X)
^\d{6}(18|19|20)\d{2}(0[1-9]|1[0-2])(0[1-9]|[12]\d|3[01])\d{3}[\dXx]$

# 日期(支持YYYY-MM-DD、YYYY/MM/DD)
^\d{4}[-/](0[1-9]|1[0-2])[-/](0[1-9]|[12]\d|3[01])$

# 时间(24小时制,HH:MM:SS)
^([01]\d|2[0-3]):([0-5]\d):([0-5]\d)$

# 信用卡号(16位,支持空格分隔)
^(?:\d{4}[-\s]?){3}\d{4}$

# 提取HTML标签内容(如<div>内容</div>)
<[^>]+>(.*?)</[^>]+>

# 匹配中文字符
[\u4e00-\u9fa5]

# 去除注释(//单行注释)
\/\/.*$

# 匹配JSON键值对(简单版)
"([^"]+)":\s*"([^"]+)"

# 匹配Windows文件路径
^[a-zA-Z]:\\(?:[^\\/:*?"<>|\r\n]+\\)*[^\\/:*?"<>|\r\n]*$

# 匹配Linux文件路径
^\/(?:[^\/\n]+\/)*[^\/\n]*$

# 匹配图片文件名(支持常见格式)
^.+\.(jpg|jpeg|png|gif|bmp|webp)$

1.7 Linux 文本处理 “三剑客”

  • 命令补全:按 Tab
  • 历史命令:/ 键切换,history 查看所有
  • 管道符 |ls -l /home | grep "txt"(筛选 txt 文件)
  • 重定向 >ls -l > file_list.txt(输出写入文件)echo "hi" >> file_list.txt(追加)

1.7.1 grep(文本搜索工具)

grep 是 Linux/Unix 系统中最常用的文本搜索工具之一,全称为 Global Regular Expression Print(全局正则表达式打印)。grep 命令常用的选项(OPTION)总结:

选项 全称 功能描述
-i --ignore-case 忽略大小写,匹配时不区分字母的大小写
-v --invert-match 反向匹配,只显示不包含匹配模式的行
-n --line-number 显示匹配行的行号
-r --recursive 递归搜索,在指定目录下的所有子目录和文件中查找
-E --extended-regexp 使用扩展正则表达式(支持 +?|等元字符)
-F --fixed-strings 将模式视为固定字符串(非正则表达式),等效于 fgrep
-w --word-regexp 只匹配完整单词(被非单词字符包围的匹配项)
-l --files-with-matches 只显示包含匹配模式的文件名,不显示具体匹配内容
-L --files-without-match 只显示不包含匹配模式的文件名
-c --count 统计每个文件中匹配模式的行数
-o --only-matching 只显示匹配模式的部分,而非整行
-h --no-filename 搜索多个文件时,不显示文件名
-H --with-filename 搜索多个文件时,显示文件名(默认行为)

grep命令示例:

# 递归查找当前目录下所有.log文件中包含"ERROR"的行,并显示行号
grep -rn "ERROR" --include="*.log" ./

# 在access.log中查找2024年3月期间出现的500错误日志
grep -E "^2024-03-[0-9]{2}.* 500 " access.log

# 在app.log中查找包含"Timeout"的行,并显示其前3行和后2行
grep -A 2 -B 3 "Timeout" app.log

# 查找系统日志中的警告信息,但排除包含"ignored"的条目
grep "warning" /var/log/syslog | grep -v "ignored"

# 统计当前目录下所有.txt文件中包含"TODO"的总行数
grep -c "TODO" *.txt

# 将app.bin视为文本文件,查找其中包含"version=1.0"的内容
grep -a "version=1.0" app.bin

# 在config.ini中以固定字符串形式查找"DEBUG"(不使用正则匹配)
grep -F "DEBUG" config.ini

# 递归查找当前目录下所有.py文件中包含"import pandas"的文件,并只显示文件名
grep -rl "import pandas" --include="*.py" ./

# 在报告.md中查找包含"销售额"的内容
grep -a "销售额" 报告.md

# 从access.log中提取IP地址,筛选出非POST请求的相关IP
grep -Eo "^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+" access.log | grep -B1 "POST" | grep -v "POST"

1.7.2 sed(文本编辑工具)

sed(Stream Editor,流编辑器)是一个在 Linux 和类 Unix 系统中广泛使用的文本处理工具,它可以对文本文件或者标准输入进行过滤和转换操作。以下是 sed 常用参数的表格总结,包含参数说明和具体用法示例:

参数 含义 用法示例
-n 静默模式,只输出经处理的行(默认输出所有行) sed -n '/error/p' log.txt 只打印包含 "error" 的行
-i 直接修改文件内容(原地编辑),可加后缀备份 sed -i.bak 's/old/new/' data.txt 替换内容并创建 .bak 备份
-e 执行多个编辑命令 sed -e 's/foo/bar/' -e '/^#/d' config.txt 替换 foo→bar 并删除注释行
-f 从脚本文件读取命令 sed -f commands.sed input.txt 执行 commands.sed 中的所有命令
-r 支持扩展正则表达式(无需转义 +*?() 等) sed -r 's/(name|age)=//' info.txt 移除 "name=" 或 "age=" 前缀 |
-E -r(某些系统兼容用) sed -E 's/([0-9]+)/\1/' nums.txt 提取数字(扩展正则语法)
-s 将多个文件视为独立处理,而非连续流 sed -s '1i Header' *.txt 给每个文件开头加 Header

1.7.2.1 替换操作(最常用)

# 格式:s/原字符串/新字符串/[选项]
sed 's/old/new/' file.txt       # 替换每行第一个"old"为"new"
sed 's/old/new/g' file.txt      # 替换每行所有"old"为"new"(g=global)
sed 's/old/new/2' file.txt      # 替换每行第二个"old"为"new"
sed 's/old/new/i' file.txt      # 忽略大小写替换(i=ignore case)

1.7.2.2 按行号操作

sed '3d' file.txt               # 删除第3行
sed '3s/old/new/' file.txt      # 仅替换第3行的"old"为"new"
sed '3,5d' file.txt             # 删除第3到5行
sed '3a new_line' file.txt      # 在第3行后追加"new_line"
sed '3i new_line' file.txt      # 在第3行前插入"new_line"

1.7.2.3 按模式匹配操作

sed '/pattern/d' file.txt       # 删除包含"pattern"的行
sed '/pattern/s/old/new/' file.txt  # 仅在包含"pattern"的行中替换"old"为"new"
sed -n '/pattern/p' file.txt    # 仅打印包含"pattern"的行(-n抑制默认输出,p=print)

1.7.2.4 多个命令组合

# 用-e执行多个命令:删除空行并替换"old"为"new"
sed -e '/^$/d' -e 's/old/new/g' file.txt

1.7.2.5 正则表达式高级用法

# 替换以"http"开头的行为"URL: 原内容"
sed 's/^http.*/URL: &/' file.txt  # &表示匹配到的整个字符串

# 提取括号中的内容(如"name(John)" → "John")
sed 's/.*(\(.*\)).*/\1/' file.txt  # \1表示第一个捕获组

1.7.3 awk(文本分析工具)

awk 是一种强大的文本处理工具,尤其擅长处理结构化文本(如表格数据、日志等),能够按行处理文本并根据指定规则提取、转换或计算数据。它支持模式匹配、条件判断和循环,常与 sedgrep 配合使用,是 Linux 系统中文本分析的核心工具之一。

1.7.3.1 AWK 核心参数表

参数 英文全称 功能说明 示例
-F fs Field Separator 指定输入字段分隔符(默认是任意空白字符,如空格、Tab) awk -F ',' '{print $1}' data.csv(以逗号分隔字段,打印第 1 列)
-v var=val Variable 定义 AWK 脚本内的变量(在脚本执行前初始化) awk -v num=5 '{print $1 + num}' data.txt(定义变量 num=5,第 1 列加 5 后打印)
-f script.awk File 从指定文件中读取 AWK 脚本(适用于复杂脚本,避免命令行过长) awk -f analysis.awk log.txt(执行 analysis.awk 中的脚本处理 log.txt)
-m[fr] val Memory Limit 限制 AWK 使用的内存(-mf 限制数据区,-mr 限制记录区,较少用) awk -mf 10M '{print $0}' large.txt(限制数据区内存为 10MB)
-O Optimize 开启脚本优化(部分 AWK 版本支持,如 GNU AWK) awk -O '{复杂脚本}' data.txt(优化脚本执行效率)
-W option Warning/Option GNU AWK 扩展参数,用于启用警告或特定功能(如 -W posix 兼容 POSIX 标准) awk -W posix '{print $0}' data.txt(按 POSIX 标准执行脚本)

1.7.3.2 AWK 基础语法与工作流程

AWK 脚本的核心格式为:

awk 'BEGIN {初始化操作} 条件 {处理动作} END {收尾操作}' 输入文件

各部分功能说明:

  • BEGIN 块:脚本执行前仅运行一次,用于初始化变量、设置输出格式(如打印表头)。

  • 条件 - 动作块:对输入文件的每一行循环执行:

    • 先判断 “条件” 是否成立(如行号、字段值匹配);
    • 条件成立则执行 “处理动作”(如打印字段、计算数值)。
    • 若省略 “条件”,则对所有行执行 “处理动作”。
  • END 块:所有行处理完成后仅运行一次,用于输出汇总结果(如统计总数、平均值)。

AWK 提供预定义变量,简化文本处理,核心变量如下:

内置变量 功能说明 示例
$0 当前处理的整行文本 awk '{print $0}' data.txt(打印所有行)
$n 当前行的第 n 个字段(n 为正整数,由 -F 指定的分隔符拆分) awk -F ',' '{print $2}' data.csv(打印 CSV 的第 2 列)
NF Number of Fields,当前行的总字段数 awk '{print NF}' data.txt(打印每行的字段数)
NR Number of Records,当前处理的行号(全局行号,跨文件累加) awk '{print NR, $0}' a.txt b.txt(打印 a.txt 和 b.txt 的所有行及行号)
FNR File Number of Records,当前文件内的行号(多文件时重置) awk '{print FNR, $0}' a.txt b.txt(a.txt 和 b.txt 分别从 1 开始计数行号)
FS Field Separator,输入字段分隔符(同 -F 参数,可在脚本内修改) awk 'BEGIN{FS=","} {print $3}' data.csv(等价于 -F ','
OFS Output Field Separator,输出字段分隔符(默认是空格) awk 'BEGIN{OFS=","} {print$1, $2, $3}' data.txt(将 data.txt 文件中每行的前 3 个字段,以逗号作为分隔符输出)

1.7.3.3 AWK 常用场景与实战命令

  1. 提取 CSV 文件的指定列(如第 1 列和第 4 列)

    # 以逗号为分隔符,打印第1列和第4列,用制表符分隔输出
    awk -F ',' 'BEGIN{OFS="\t"} {print \$1, \$4}' student.csv
    
  2. 提取行号在 10-20 之间的行

    # NR==10\~20 表示行号在10到20之间
    awk 'NR>=10 && NR<=20 {print NR, \$0}' log.txt
    
  3. 提取包含指定关键词的行(如含 “error” 的日志行)

    # /error/ 是正则表达式,匹配含“error”的行(不区分大小写可加 IGNORECASE=1)
    awk '/error/ {print NR, $0}' app.log
    # 不区分大小写匹配“Error”或“ERROR”
    awk 'BEGIN{IGNORECASE=1} /error/ {print $0}' app.log
    
  4. 统计文件总行数

    # END块中打印NR(最后一行的NR即为总行数)
    awk 'END{print "总行数:", NR}' data.txt
    
  5. 统计某列的总和与平均值(如 CSV 第 3 列是分数,求总和与平均分)

    awk -F ',' '
      BEGIN{sum=0}  # 初始化总和为0
      $3!=""{sum+=$3; count++}  # 第3列非空时累加,计数有效行
      END{
        print "总分:", sum;
        print "平均分:", sum/count;  # 计算并打印平均分
      }
    ' score.csv
    
  6. 统计关键词出现次数(如统计日志中 “warning” 的次数)

    awk '/warning/ {count++} END{print "Warning次数:", count}' app.log
    
  7. 将空格分隔的文本转为 CSV 格式(用逗号分隔)

    # 设置输出分隔符为逗号,打印所有字段
    awk 'BEGIN{OFS=","} {print $1, $2, $3, $4}' data.txt > data.csv
    
  8. 为输出添加表头和表尾(如给统计结果加说明)

    # 统计分数大于90的学生,添加表头和统计结果
    awk -F ',' '
      BEGIN{print "姓名", "分数"; print "--------"}  # 表头
      $2>90 {print $1, $2; count++}  # 打印分数>90的学生,计数
      END{print "--------"; print "优秀学生数:", count}  # 表尾
    ' score.csv
    
  9. 按行号合并两个文件(如 file1 的第 1 行与 file2 的第 1 行合并)

    # NR==FNR 表示处理第一个文件(file1),将其内容存到数组a中;后续处理file2,拼接内容
    awk 'NR==FNR {a[NR]=$0} NR>FNR {print a[FNR], $0}' file1.txt file2.txt
    
  10. 筛选 “第 2 列是男生” 且 “第 3 列分数 > 85” 的学生

    # 多条件用 &&(且)、||(或)连接,字符串匹配需加双引号
    awk -F ',' '$2=="男" && $3>85 {print $1, $3}' student.csv
    

二、Bash 编程

2.1 基础部分

2.1.1 脚本基础

  • 脚本头部:所有 Bash 脚本第一行应为 #!/bin/bash(指定解释器)
  • 创建脚本touch script.sh
  • 执行权限chmod +x script.sh
  • 运行方式./script.shbash script.sh

2.1.2 变量操作

# 变量定义(等号两侧无空格)
name="Bash"
version=5.1

# 变量使用
echo "Name: $name, Version: $version"
echo "Full info: ${name}1.9.2"  # 变量边界清晰化

# 命令结果赋值
files=$(ls)
dates=`date`  # 过时语法,推荐使用$()

# 只读变量
readonly PI=3.14159

# 删除变量
unset version

2.1.3 输入输出

# 输出带颜色文本
echo -e "\033[31mRed text\033[0m"  # 红色文本

# 读取用户输入
read -p "Enter your name: " username
echo "Hello, $username"

# 重定向
command > output.txt    # 覆盖写入
command >> output.txt   # 追加写入
command 2> error.log    # 错误输出
command &> all_outputs  # 所有输出

2.1.4 条件判断

# 文件判断
if [ -f "file.txt" ]; then
    echo "Regular file exists"
elif [ -d "dir" ]; then
    echo "Directory exists"
else
    echo "Not found"
fi

# 数值比较
num=10
if (( num > 5 )); then
    echo "$num is greater than 5"
fi

# 字符串比较
str="test"
if [ "$str" = "test" ]; then
    echo "Strings match"
fi

# 逻辑运算
if [ -f "file.txt" ] && [ -r "file.txt" ]; then
    echo "File exists and is readable"
fi

2.1.5 循环结构

# for循环 - 列表
for fruit in apple banana cherry; do
    echo "Fruit: $fruit"
done

# for循环 - 范围
for i in {1..5}; do
    echo "Number: $i"
done

# while循环
count=1
while [ $count -le 3 ]; do
    echo "Count: $count"
    ((count++))
done

# until循环(条件为假时执行)
until [ $count -gt 5 ]; do
    echo "Count: $count"
    ((count++))
done

2.1.6 函数

# 基本函数
greet() {
    echo "Hello, $1!"  # $1是第一个参数
}
greet "World"  # 调用函数

# 返回值
add() {
    return $(( $1 + $2 ))
}
add 3 5
echo "Result: $?"  # $?获取上一个命令返回值

# 函数参数
show_args() {
    echo "Total args: $#"  # 参数数量
    echo "All args: $*"    # 所有参数
}
show_args 1 2 3

2.1.7 运算符

2.1.7.1 算术运算符

用于数值计算,常用在 $((...))$[...])expr 表达式中。

运算符 描述 示例(a=5, b=3) 结果
+ 加法 $((a + b)) 8
- 减法 $((a - b)) 2
* 乘法 $((a * b)) 15
/ 除法(整数除法) $((a / b)) 1(5÷3 取整)
% 取余(模运算) $((a % b)) 2(5÷3 的余数)
++ 自增 $((a++))$((++a)) 5(后增)或 6(前增)
-- 自减 $((a--))$((--a)) 5(后减)或 4(前减)
** 幂运算(Bash 4.0+) $((a **b)) 125(5³)

2.1.7.2 比较运算符

用于比较数值或字符串,根据使用场景分为数值比较字符串比较

数值比较(常用在 [ ](( )) 中):

运算符 描述 示例(a=5, b=3) 结果
-eq 等于 [ $a -eq $b ] false(5≠3)
-ne 不等于 [ $a -ne $b ] true(5≠3)
-gt 大于 [ $a -gt $b ] true(5>3)
-lt 小于 [ $a -lt $b ] false(5<3 不成立)
-ge 大于等于 (( a >= b )) true(5≥3)
-le 小于等于 (( a <= b )) false(5≤3 不成立)

注意:在 (( )) 中可直接使用 >、<、>=、<=、==、!= 等符号,更直观。

字符串比较(常用在 [ ][[ ]] 中):

运算符 描述 示例(s1="abc", s2="def") 结果
=== 等于 [ "$s1" = "$s2" ] false("abc"≠"def")
!= 不等于 [[ "$s1" != "$s2" ]] true("abc"≠"def")
-z 字符串长度为 0 [ -z "$empty_str" ] true(若 empty_str为空)
-n 字符串长度不为 0 [ -n "$s1" ] true("abc" 长度≠0)
> 字典序大于(仅 [[ ]]支持) [[ "$s1" > "$s2" ]] false("abc" 在字典序中小于 "def")
< 字典序小于(仅 [[ ]]支持) [[ "$s1" < "$s2" ]] true("abc" 在字典序中小于 "def")

2.1.7.3 逻辑运算符

用于组合多个条件判断,实现复杂逻辑。

运算符 描述 示例 结果
&& 逻辑与(两边都为真则为真) [ $a -gt 0 ] && [ $b -lt 10 ] 两边条件都满足时为真
|| 逻辑或(至少一边为真则为真) [ $num1 -lt 5 ] || [ $num2 -gt 10 ] 至少一边为真则为真
! 逻辑非(取反) ! [ $a -eq $b ] a≠b时为真

2.1.7.4 文件测试运算符

用于检查文件属性(如是否存在、是否为目录等),常用在 [ ] 中。

运算符 描述 示例
-e file 文件或目录是否存在 [ -e "test.txt" ]
-f file 是否为普通文件(非目录) [ -f "test.txt" ]
-d file 是否为目录 [ -d "docs" ]
-r file 是否有读权限 [ -r "test.txt" ]
-w file 是否有写权限 [ -w "test.txt" ]
-x file 是否有执行权限 [ -x "script.sh" ]
-s file 文件是否非空(大小 > 0) [ -s "test.txt" ]
-L file 是否为符号链接 [ -L "link.txt" ]

2.2 进阶部分

2.2.1 数组操作

# 定义数组
fruits=("apple" "banana" "cherry")

# 访问元素
echo "First: ${fruits[0]}"
echo "All: ${fruits[@]}"  # 所有元素

# 数组长度
echo "Count: ${#fruits[@]}"

# 添加元素
fruits+=("date")

# 遍历数组
for fruit in "${fruits[@]}"; do
    echo $fruit
done

2.2.2 字符串处理

str="Hello, Bash Programming"

# 长度
echo "Length: ${#str}"

# 截取
echo "${str:0:5}"   # 从0开始取5个字符
echo "${str:7}"     # 从7开始取到结尾

# 替换
echo "${str/Bash/Shell}"  # 替换第一个匹配
echo "${str// /-}"        # 替换所有空格为连字符

# 大小写转换
echo "${str^^}"  # 全部大写
echo "${str,,}"  # 全部小写

2.2.3 高级条件表达式

# 使用[[ ]]进行更强大的条件判断
if [[ $var =~ ^[0-9]+$ ]]; then
    echo "Is a number"
fi

# 模式匹配
filename="document.txt"
if [[ $filename == *.txt ]]; then
    echo "Text file"
fi

2.2.4 进程处理

# 后台运行
long_running_command &

# 获取进程ID
echo "PID: $!"

# 等待进程完成
wait $!
echo "Command finished"

# 管道与组合命令
ps aux | grep "bash"  # 管道
command1 && command2  # 逻辑与(command1成功才执行command2)
command1 || command2  # 逻辑或(command1失败才执行command2)

2.2.5 错误处理与调试

# 设置严格模式
set -euo pipefail
# -e: 命令失败则脚本退出
# -u: 使用未定义变量则报错
# -o pipefail: 管道中任何命令失败则整个管道失败

# 调试模式运行脚本
# bash -x script.sh

# 错误陷阱
trap 'echo "Error at line $LINENO"; exit 1' ERR

2.2.6 正则表达式

text="Email: user@example.com"

if [[ $text =~ [A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,} ]]; then
    echo "Valid email found: ${BASH_REMATCH[0]}"
fi

2.2.7 关联数组(字典)

# 声明关联数组
declare -A user

# 赋值
user["name"]="John"
user["age"]="30"
user["city"]="New York"

# 访问
echo "Name: ${user["name"]}"

# 遍历
for key in "${!user[@]}"; do
    echo "$key: ${user[$key]}"
done

2.2.8 read 命令

Linux/Unix Shell(如 Bash、Zsh) 中,read 是一个核心的内置命令,主要作用是从标准输入(stdin) 读取用户输入的文本数据,并将其赋值给指定的变量,实现脚本与用户的交互,或处理文件 / 管道传递的内容。

选项 功能描述 示例 示例说明
-p "提示信息" 显示提示文本,无需额外 echo read -p "请输入用户名:" user 显示 "请输入用户名:" 并等待输入,保存到变量 user
-t 秒数 设置超时时间,超时后退出 if read -t 5 -p "5秒内输入:" input; then ... 5 秒内未输入则执行 else分支
-n 字符数 读取指定字符后自动结束(无需回车) read -n 1 -p "确认(y/n):" confirm 输入 1 个字符后立即结束(如 y 或 n)
-s 静默模式,输入不显示(隐藏输入) read -s -p "请输入密码:" pass 输入密码时不在终端显示内容
-a 数组名 将输入按空格分割存入数组 read -a fruits -p "输入水果:" 输入 "苹果 香蕉" 会存入数组 fruits
-d 分隔符 自定义结束符(默认是换行) read -d ";" -p "输入内容(;结束):" text 输入到 ";" 时停止,如 "abc;" 会保存 "abc"
无选项 读取整行到指定变量 read address 读取一整行输入到变量 address
不指定变量 输入保存到默认变量 REPLY read -p "输入内容:" 输入内容会保存到 $REPLY
多变量 按空格分割输入到多个变量 read name age -p "姓名 年龄:" 输入 "张三 25" 会分别存入 nameage
从文件读取 结合重定向读取文件内容 while read line; do echo $line; done < file.txt 逐行读取 file.txt内容并打印

2.3 实用技巧

  1. 参数解析:使用 getopts 处理命令行选项

    while getopts "f:v" opt; do
        case $opt in
            f) file="$OPTARG" ;;
            v) verbose=1 ;;
            \?) echo "Invalid option: -$OPTARG" >&2 ;;
        esac
    done
    
  2. here 文档:嵌入多行文本

    cat << EOF > config.txt
    server=localhost
    port=8080
    timeout=30
    EOF
    
  3. 函数库:创建可重用的函数库

    # 在脚本中引入函数库
    source ./functions.lib
    # 或
    . ./functions.lib
    
输出字段 含义
load average: 0.80, 0.95, 1.00 系统负载(1/5/15 分钟平均):值接近 CPU 核心数(如 4 核为 4.0)表示负载满
%us 用户态 CPU 使用率:进程(如应用程序)占用的 CPU 比例
%sy 系统态 CPU 使用率:内核操作(如内存管理、I/O)占用的 CPU 比例
%id 空闲 CPU 使用率:值越低表示 CPU 越繁忙
%wa I/O 等待 CPU 使用率:值高表示磁盘 I/O 慢,CPU 等待 I/O 完成

2.4 日志分析脚本

#!/bin/bash
# 声明脚本使用bash解释器执行

# 日志分析脚本 - 综合展示 grep, sed, awk 用法
# 功能:分析Web服务器日志,生成访问统计报告
# 支持的日志格式:Apache/Nginx默认日志格式(可通过调整字段索引适配其他格式)

# 检查参数是否正确
# $# 表示命令行参数的数量,-ne 表示不等于
if [ $# -ne 1 ]; then
    echo "用法: $0 <日志文件路径>"  # $0 表示脚本本身的文件名
    exit 1  # 异常退出,返回状态码1
fi

LOG_FILE="$1"  # 将第一个参数赋值给LOG_FILE变量,存储日志文件路径

# 检查文件是否存在
# -f 用于检查是否为普通文件
if [ ! -f "$LOG_FILE" ]; then
    echo "错误: 文件 $LOG_FILE 不存在!"
    exit 1  # 异常退出
fi

# 定义颜色常量,用于美化输出(ANSI转义序列)
RED='\033[0;31m'      # 红色:用于标识错误状态
GREEN='\033[0;32m'    # 绿色:用于标识成功状态
YELLOW='\033[1;33m'   # 黄色:用于标识警告/标题
BLUE='\033[0;34m'     # 蓝色:用于标识重要信息
NC='\033[0m'          # 无颜色:重置颜色设置

# 函数:显示脚本头部信息
display_header() {
    # echo -e 允许解析转义字符
    echo -e "\n${BLUE}======================================"
    echo "         日志分析报告                 "
    echo "======================================${NC}"
    echo "分析文件: $LOG_FILE"  # 显示被分析的日志文件路径
    echo "分析时间: $(date)"   # $(date) 执行date命令并插入结果
    echo -e "--------------------------------------\n"
}

# 函数:统计不同状态码的出现次数
count_status_codes() {
    echo -e "${YELLOW}1. 状态码统计:${NC}"  # 输出 section 标题
  
    # 管道操作详解:
    # 1. awk '{print $9}' 提取日志第9个字段(HTTP状态码)
    # 2. sort 对状态码进行排序(为uniq做准备)
    # 3. uniq -c 统计相邻重复行的出现次数(-c显示计数)
    # 4. sort -nr 按计数逆序排序(-n按数字排序,-r逆序)
    # 5. while循环读取每一行的计数和状态码
    awk '{print $9}' "$LOG_FILE" | sort | uniq -c | sort -nr | while read count code; do
        # 使用case判断状态码类型,设置不同颜色
        case $code in
            2*) color=$GREEN ;;  # 2xx 系列:成功状态码(如200)
            3*) color=$BLUE ;;   # 3xx 系列:重定向状态码(如301)
            4*) color=$YELLOW ;; # 4xx 系列:客户端错误(如404)
            5*) color=$RED ;;    # 5xx 系列:服务器错误(如500)
            *) color=$NC ;;      # 其他未分类状态码
        esac
        # 输出计数和带颜色的状态码,最后重置颜色
        echo -e "  $count  ${color}$code${NC}"
    done
    echo  # 输出空行,分隔不同section
}

# 函数:找出访问量最高的前10个IP地址
top_ips() {
    echo -e "${YELLOW}2. 访问量最高的前10个IP地址:${NC}"
  
    # 管道操作详解:
    # 1. awk '{print $1}' 提取日志第1个字段(客户端IP地址)
    # 2. sort 对IP地址排序
    # 3. uniq -c 统计每个IP出现的次数
    # 4. sort -nr 按访问次数逆序排序
    # 5. head -n 10 只取前10条结果
    # 6. while循环输出计数和IP地址
    awk '{print $1}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -n 10 | while read count ip; do
        echo "  $count  $ip"
    done
    echo
}

# 函数:找出请求最多的前10个URL
top_urls() {
    echo -e "${YELLOW}3. 请求最多的前10个URL:${NC}"
  
    # 管道操作详解:
    # 1. awk '{print $7}' 提取日志第7个字段(请求的URL路径)
    # 2. 后续操作与top_ips类似,统计并排序URL的访问次数
    awk '{print $7}' "$LOG_FILE" | sort | uniq -c | sort -nr | head -n 10 | while read count url; do
        echo "  $count  $url"
    done
    echo
}

# 函数:分析404错误并提取有意义的信息
analyze_404_errors() {
    echo -e "${YELLOW}4. 最近的10个404错误:${NC}"
  
    # 管道操作详解:
    # 1. grep " 404 " 筛选包含404状态码的日志行(前后空格避免匹配4040等)
    # 2. tail -n 10 只取最后10条(最近的)404错误记录
    # 3. sed 命令链:
    #    -e 's/\?.*//' 移除URL中的查询参数(从?开始的部分)
    #    -e 's/"//g' 移除所有引号
    # 4. awk 格式化输出IP地址($1)和URL($7)
    grep " 404 " "$LOG_FILE" | tail -n 10 | \
    sed -e 's/\?.*//' -e 's/"//g' | \
    awk '{printf "  %s  %s\n", $1, $7}'
  
    echo
}

# 函数:按小时统计访问量
hourly_stats() {
    echo -e "${YELLOW}5. 每小时访问统计:${NC}"
  
    # awk 脚本详解:
    # 主处理块:
    # - $4 是日志中的日期时间字段(格式如:[10/Oct/2000:13:55:36)
    # - split($4, date, /:/) 按冒号分割字符串,存储到date数组
    # - hour = date[2] 提取小时部分(数组索引从1开始)
    # - hours[hour]++ 对每个小时进行计数
  
    # END块(所有行处理完后执行):
    # - 循环0-23小时,格式化输出每个小时的访问量
    # - hours[h] + 0 确保即使该小时无数据也显示0而非空
    awk '{
        split($4, date, /:/);  # 分割日期时间字段
        hour = date[2];        # 获取小时部分
        hours[hour]++          # 计数
    }
    END {
        for (h = 0; h < 24; h++) {
            printf "  %02d:00 - %02d:59: %d\n", h, h, hours[h] + 0
        }
    }' "$LOG_FILE"
    echo
}

# 函数:检测可能的爬虫活动
detect_crawlers() {
    echo -e "${YELLOW}6. 可能的爬虫活动:${NC}"
  
    # 管道操作详解:
    # 1. grep 筛选:
    #    -E 使用扩展正则表达式
    #    -i 忽略大小写
    #    匹配包含常见爬虫标识(bot|crawl|spider|slurp)的User-Agent
    # 2. awk 提取IP($1)和User-Agent相关字段($12到$15)
    # 3. sort | uniq -c | sort -nr 统计并按次数排序
    # 4. head -n 5 只显示前5个
    # 5. sed 清理输出:
    #    -e 's/"//g' 移除引号
    #    -e 's/\(.*\)/  \1/' 在每行前添加缩进
    grep -E -i '"Mozilla/5.0.*(bot|crawl|spider|slurp)"' "$LOG_FILE" | \
    awk '{print $1, $12, $13, $14, $15}' | \
    sort | uniq -c | sort -nr | head -n 5 | \
    sed -e 's/"//g' -e 's/\(.*\)/  \1/'
  
    echo
}

# 主函数:执行所有分析步骤
main() {
    display_header        # 显示报告头部
    count_status_codes    # 统计状态码
    top_ips               # 分析TOP IP
    top_urls              # 分析TOP URL
    analyze_404_errors    # 分析404错误
    hourly_stats          # 按小时统计
    detect_crawlers       # 检测爬虫活动
  
    # 显示报告结束信息
    echo -e "${BLUE}======================================"
    echo "         分析完成                     "
    echo "======================================${NC}"
}

# 启动主函数,开始执行分析
main