Linux 命令这类东西,平时看着零散,真到线上出问题的时候,能想起来几条就是几条。磁盘满了要立刻定位大文件,服务起不来要马上看端口和日志,接口超时要快速判断是 DNS、网络还是后端进程卡死——这些场景不会给你翻手册的时间。这篇文章面向零基础到中级运维、后端开发、测试和刚接触服务器的同学,把日常 90% 场景会用到的 Linux 高频命令按“文件、文本、进程、权限、网络、日志”六条线重新梳理一遍。
先说清楚这篇文章能给你什么。它不是一本命令手册的搬运,而是按“遇到什么问题 → 用哪条命令 → 怎么看输出 → 怎么判断结论”的顺序组织。每条命令都给出可直接复制的写法,同时把最容易踩的坑写出来,比如 rm -rf 的变量为空问题、sed -i 改配置前必须先备份、ps aux 里 %CPU 是进程生命周期均值而不是瞬时值、df 满了但 du 对不上通常是删除未释放的文件句柄。
阅读门槛很低:一台能 SSH 登录的 Linux 机器就够,云服务器、虚拟机、WSL、Docker 容器都行。文中命令以 Bash 为准,大部分在 CentOS、Ubuntu、Debian、Alpine 上通用,少数涉及包管理的地方会分别标注。如果你只想快速上手,建议按第 4 到第 8 章的顺序边看边敲;如果你已经有一定基础,可以直接跳到第 6、7、9 章,那几节是线上排障真正的重灾区。
需要提前说明的是,涉及 rm、chmod、chown、iptables、kill -9 这类有破坏性的命令,本文只讲正确用法和风险边界,建议全部先在测试环境验证,生产环境操作前做好备份与变更记录。命令本身没有立场,用错地方就是事故。
1. Linux 高频命令核心能力速览
先给一张全局表,把这次要覆盖的内容和门槛讲清楚。很多同学学命令效率低,是因为没有建立“命令 → 场景”的映射,背了 awk 却不知道什么时候该用它,记住了 ss 却分不清和 netstat 的关系。下面这张表就是用来建立映射的。
| 能力项 | 说明 |
|---|---|
| 项目类型 | Linux 命令行运维技能梳理,非软件项目 |
| 覆盖范围 | 文件目录、文本处理、进程端口、权限用户、磁盘存储、网络诊断、日志分析、定时任务 |
| 学习时长 | 90 分钟可完成一轮通读与跟练,熟练需要持续在真实环境使用 |
| 环境要求 | 任意 Linux 发行版,Bash 4.0 以上;云服务器、虚拟机、WSL、容器均可 |
| 权限要求 | 查看类命令普通用户可执行;涉及系统目录、服务管理、用户管理需 sudo 或 root |
| 是否依赖图形界面 | 不需要,纯终端操作 |
| 常用工具链 | coreutils、procps、iproute2、grep、sed、awk、findutils、systemd、curl |
| 适合场景 | 服务器日常巡检、故障排查、日志分析、部署脚本编写、批量处理 |
| 不适合场景 | 替代监控告警系统、替代专业 APM 与链路追踪工具 |
| 掌握难度 | 基础命令低;awk、sed 正则与 systemd 单元管理中等偏上 |
再拆一层,把命令按“使用频率”和“排障价值”做个粗略分层,方便你分配学习精力。
| 分层 | 代表命令 | 建议掌握程度 |
|---|---|---|
| 每天都会用 | ls、cd、pwd、cat、tail、grep、ps、df、du、systemctl |
熟练到不用思考,参数顺手就来 |
| 排障必用 | ss、lsof、top、free、journalctl、find、curl |
知道输出每一列含义,能下结论 |
| 提效利器 | awk、sed、xargs、sort、uniq、cut、tar |
能组合成一行命令解决批量问题 |
| 谨慎使用 | rm、chmod、chown、kill、iptables、dd |
清楚风险边界,操作前备份 |
这张表的价值在于:你不需要把几百条命令全背下来,把第一层和第二层吃透,已经能覆盖绝大多数线上场景。第三层是拉开效率差距的地方,第四层是决定你会不会出事故的地方。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 适用场景与使用边界
Linux 命令的适用面很广,但也不是万能的。先把边界讲清楚,避免用错工具浪费时间。
适合使用的场景主要有几类。第一类是服务器日常巡检,登录机器后快速确认负载、内存、磁盘、关键服务状态,这套动作熟练之后三分钟能过一遍。第二类是故障定位,包括服务起不来、端口不通、接口 502、CPU 飙高、磁盘写满、日志报错,这些都有相对固定的排查路径。第三类是批量处理,比如清理七天前的日志、统计访问量 Top 10 的 IP、批量替换配置文件里的域名。第四类是编写部署与运维脚本,bash 加上这些命令足以支撑大量自动化任务。
不适合的场景也要说清楚。命令行不适合做长期监控,top 看一眼可以,7×24 的指标采集应该交给 Prometheus、Zabbix 这类系统;命令行不适合做复杂的数据分析,awk 能处理文本聚合,但真要做多维分析还是导入数据库更稳妥;命令行也不适合替代日志平台,机器少的时候 grep 很爽,几十台机器还靠 SSH 逐台 grep,效率就会崩掉,这时候应该上集中式日志。
安全边界同样重要。第一,任何删除、覆盖、权限变更操作,必须确认目标路径和影响范围,尤其是带变量拼接的脚本,变量为空时 rm -rf $DIR/ 可能变成 rm -rf /,正确写法是加引号并做非空校验。第二,生产环境修改配置前先备份,sed -i 直接改文件是常见事故来源,稳妥做法是先输出到临时文件再覆盖。第三,不要随意关闭防火墙、不要随意给 777 权限、不要用 root 跑业务进程,这些做法短期省事,长期都是隐患。第四,涉及日志和用户数据时注意隐私合规,导出的日志文件要控制访问范围,避免把含手机号、身份证、令牌的内容外发。
3. 环境准备与前置条件
这一节把实验环境准备好,后面所有命令都能直接跟着敲。如果你已经有可用的 Linux 机器,可以快速扫一眼确认几项。
第一,确认系统版本和 Shell 类型。不同发行版的包管理器和默认配置不同,先搞清楚自己在哪。
bash复制# 查看发行版信息
cat /etc/os-release
# 查看内核版本
uname -r
# 查看当前 Shell
echo $SHELL
bash --version | head -1
第二,确认常用工具是否齐全。最小化安装的系统经常缺 lsof、net-tools、curl、vim,缺什么装什么。
bash复制# Debian / Ubuntu 系
sudo apt update
sudo apt install -y curl vim lsof net-tools procps iproute2
# CentOS / RHEL / Rocky 系
sudo yum install -y curl vim lsof net-tools procps iproute
第三,准备一个练习目录,避免在系统目录里乱操作。
bash复制mkdir -p ~/linux-lab/{logs,conf,data}
cd ~/linux-lab
第四,确认当前用户和权限。后面涉及 systemctl、chown 的命令需要 sudo,提前确认账号有没有这个能力。
bash复制whoami
id
sudo -l
第五,确认 SSH 连接稳定。长时间操作建议用 tmux 或 screen,避免网络抖动导致命令中断,尤其是执行耗时任务时。
bash复制# 安装并启动 tmux,断线后会话仍在
sudo apt install -y tmux
tmux new -s ops
这套准备大概五分钟。如果是在容器里练习,注意容器内通常没有 systemd,systemctl 和 journalctl 会不可用,这类命令建议在虚拟机或云服务器上验证。
4. 文件与目录操作高频命令
文件操作是所有 Linux 使用的起点。这一节不讲教科书式的参数罗列,只讲实际会用到的组合。
4.1 查看与切换:ls、cd、pwd
ls 的高频参数就那么几个:-l 长格式、-a 显示隐藏文件、-h 人类可读大小、-t 按时间排序、-r 反序。组合起来最实用的是按修改时间倒序看最近变动。
bash复制# 按修改时间倒序,显示详细信息与可读大小
ls -alht
# 只看目录本身,不递归
ls -ld /var/log
# 按大小排序,找当前目录下最大的文件
ls -lhS | head -10
cd 有两个提效技巧值得记住:cd - 回到上一个目录,cd ~ 回 home。pwd 在写脚本时非常重要,因为脚本执行时的工作目录未必是你以为的那个,先 pwd 再操作能避免一堆路径问题。
4.2 复制、移动与删除:cp、mv、rm
这三条命令的风险等级依次上升。cp 和 mv 的关键参数是 -i(覆盖前询问)和 -r(递归),rm 的关键是永远不要在生产环境裸奔。
bash复制# 复制目录并保留权限与时间戳
cp -a /data/app/conf /backup/conf-$(date +%F)
# 移动并用交互模式防止误覆盖
mv -i old.log archive/old.log
# 删除前先确认匹配结果,确认无误再执行
find /data/app/logs -name "*.log" -mtime +7 -print
find /data/app/logs -name "*.log" -mtime +7 -delete
上面这段是清理日志的标准套路:先用 -print 看一眼会删哪些文件,确认范围没问题再把 -print 换成 -delete。多花十秒钟,能避免一次事故。另外强调一点,rm -rf 后面跟随变量时,务必加引号并做非空判断。
bash复制# 不推荐的写法:变量为空时会变成 rm -rf /
# rm -rf $TARGET_DIR/
# 推荐写法:加引号并校验非空
TARGET_DIR="/data/app/tmp"
if [ -n "$TARGET_DIR" ] && [ "$TARGET_DIR" != "/" ]; then
rm -rf "$TARGET_DIR"
fi
4.3 查找文件:find
find 是文件层面的主力工具,按名称、时间、大小、类型、权限都能筛,配合 -exec 或 xargs 可以做批处理。
bash复制# 查找 7 天前修改、大于 100M 的日志文件
find /var/log -type f -name "*.log" -mtime +7 -size +100M
# 查找最近 30 分钟内修改过的文件,排查是否有异常写入
find /data -type f -mmin -30
# 查找权限为 777 的文件,安全检查常用
find /var/www -type f -perm 0777
# 批量压缩:对匹配文件执行 gzip
find /data/logs -name "*.log" -mtime +3 -exec gzip {} \;
# 配合 xargs 批量处理,注意 -print0 与 -0 配对,避免文件名带空格出错
find /data/logs -name "*.log" -print0 | xargs -0 ls -lh
find 的性能问题也提一句:在大目录上执行 find / 会消耗大量 IO,生产环境建议限定路径和深度,必要时用 -maxdepth 控制。
4.4 查看文件内容:cat、less、head、tail
小文件用 cat,大文件用 less,看头尾用 head、tail。日志场景里 tail -f 是绝对高频。
bash复制# 实时跟踪日志,最常用的排障动作之一
tail -f /var/log/nginx/access.log
# 跟踪时同时关注轮转,日志切割后仍能继续跟
tail -F /var/log/app/app.log
# 查看文件最后 200 行并持续跟踪
tail -n 200 -f /var/log/app/app.log
-f 和 -F 的区别值得记一下:-f 跟的是文件描述符,日志被切割重命名后会失效;-F 会按文件名重新打开,日志轮转后依然有效。线上排障优先用 -F。
4.5 压缩与打包:tar
tar 的参数组合看着复杂,其实记住两组就够:打包压缩用 czvf,解包用 xzvf。z 是 gzip,j 是 bzip2,J 是 xz,v 显示过程,f 指定文件名。
bash复制# 打包并压缩
tar -czvf backup-$(date +%F).tar.gz /data/app
# 解压到指定目录
tar -xzvf backup-2024-01-01.tar.gz -C /tmp/restore
# 只查看包内容,不解压
tar -tzvf backup-2024-01-01.tar.gz | head -20
一个常见坑:打包时路径带绝对路径,解压时会还原到原路径,容易覆盖现有文件。稳妥做法是 cd 到目标父目录再用相对路径打包。
5. 文本处理三剑客:grep、sed、awk
这三条命令是 Linux 文本处理的核心,也是很多同学觉得难的地方。其实日常场景用不到多复杂的语法,掌握几个固定组合就能解决大部分问题。
5.1 grep:从海量文本里捞出你要的那几行
grep 的核心是筛选。常用参数:-i 忽略大小写、-n 显示行号、-r 递归目录、-v 反向匹配、-c 统计行数、-E 扩展正则、--include 限定文件类型。
bash复制# 递归搜索日志目录下的 ERROR,显示行号
grep -rn "ERROR" /var/log/app/ --include="*.log" | head -20
# 忽略大小写统计出现次数
grep -ic "timeout" /var/log/app/app.log
# 排除包含 DEBUG 的行,只看有效信息
grep -v "DEBUG" /var/log/app/app.log | tail -50
# 同时匹配多个关键词
grep -E "ERROR|FATAL|Exception" /var/log/app/app.log | tail -30
排障时最实用的套路是“先定位关键词,再看上下文”。grep -n 拿到行号后,用 sed -n '起始行,结束行p' 打印上下文,比直接翻文件高效得多。
bash复制# 假设定位到第 1200 行有异常
sed -n '1180,1230p' /var/log/app/app.log
5.2 sed:按行或按模式做替换
sed 最常用的是替换。格式是 s/原内容/新内容/标志,g 表示全局替换。
bash复制# 预览替换效果,不修改文件
sed 's/old.domain.com/new.domain.com/g' /etc/nginx/nginx.conf | grep domain
# 确认无误后原地修改,必须先备份
cp /etc/nginx/nginx.conf /etc/nginx/nginx.conf.bak.$(date +%F)
sed -i 's/old.domain.com/new.domain.com/g' /etc/nginx/nginx.conf
# 只替换匹配行,比如只改 listen 那一行
sed -i '/listen 80;/s/80/8080/' /etc/nginx/nginx.conf
# 删除空行
sed -i '/^$/d' /tmp/list.txt
必须强调:sed -i 是直接改文件,改错了没有撤销。规范流程是“先不带 -i 预览 → 备份 → 带 -i 执行 → 复查关键行”。sed 的语法在不同系统上有细微差异,macOS 上的 sed -i 需要额外参数,跨平台脚本要注意。
5.3 awk:按列处理与统计
awk 的强项是“按列取值 + 聚合统计”,Nginx 访问日志分析是它的经典场景。
bash复制# 统计访问量 Top 10 的 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -rn | head -10
# 统计状态码分布
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
# 按自定义分隔符取字段,比如冒号分隔
awk -F':' '{print $1}' /etc/passwd | head -10
# 条件过滤:找出状态码为 5xx 的请求
awk '$9 ~ /^5/ {print $1, $7, $9}' /var/log/nginx/access.log | head -20
# 求和:统计某列总流量
awk '{sum += $10} END {print sum/1024/1024 " MB"}' /var/log/nginx/access.log
awk 的内置变量记住三个就够用:$0 整行、$1 第一列、NF 列数。NR 是行号,做条件判断时也常用。上面这些组合建议直接抄下来做成自己的命令片段库,用的时候改路径就行。
5.4 管道组合的力量
单条命令能力有限,组合起来才是 Linux 的真正效率。几个典型组合:
bash复制# 找出占用空间最大的前 10 个目录
du -h --max-depth=1 /var | sort -rh | head -10
# 统计当前 ESTABLISHED 连接数最多的远端 IP
ss -ant | awk 'NR>1 {print $5}' | cut -d: -f1 | sort | uniq -c | sort -rn | head
# 批量重命名:把所有 .txt 改成 .md
for f in *.txt; do mv "$f" "${f%.txt}.md"; done
这类组合的价值在于把“多次手工操作”压缩成“一条命令”。建议平时遇到重复动作就顺手记下来,慢慢就形成了自己的工具箱。
6. 进程、端口与系统资源排查
这一节是线上排障的核心。CPU 高、内存涨、端口不通、服务假死,都在这几条命令的覆盖范围内。
6.1 看进程:ps、top、pgrep
bash复制# 查看所有进程,过滤 Java 进程
ps -ef | grep java
# 按内存占用倒序,看谁在吃内存
ps aux --sort=-%mem | head -10
# 按 CPU 占用倒序
ps aux --sort=-%cpu | head -10
# 查看进程树,理清父子关系
ps -ef --forest | head -30
# 直接按名称找 PID,比 grep 干净
pgrep -a nginx
有一个概念必须讲清楚:ps aux 输出的 %CPU 是进程整个生命周期内的平均 CPU 占用,不是当前瞬时值。想看瞬时占用要用 top。这个误解导致很多人误判。
top 的交互键值得记几个:P 按 CPU 排序、M 按内存排序、1 展开每个 CPU 核心、c 显示完整命令行、q 退出。top -p PID 可以只盯某个进程。
bash复制# 只看指定进程,并显示线程
top -H -p $(pgrep -f app.jar | head -1)
-H 显示线程模式,排查 Java 应用 CPU 飙高时,先用它找到最耗 CPU 的线程 ID,再转成十六进制去 jstack 里对照,这是标准动作。
6.2 看端口与连接:ss、lsof
ss 是 netstat 的现代替代品,速度更快,新系统默认自带。
bash复制# 查看所有监听端口及对应进程
ss -lntp
# 查看指定端口占用
ss -lntp | grep 8080
# 查看已建立的连接
ss -ant state established | head -20
# 统计各状态连接数
ss -ant | awk 'NR>1 {print $1}' | sort | uniq -c | sort -rn
lsof 更直观,能直接告诉你哪个进程占了哪个端口。
bash复制# 查看谁占用了 8080 端口
sudo lsof -i:8080
# 查看某进程打开的所有文件
sudo lsof -p $(pgrep -f app.jar | head -1) | head -30
# 查看被删除但仍被占用的文件,磁盘满的经典排查点
sudo lsof | grep deleted
最后这条非常关键。df -h 显示磁盘满了,但 du -sh 加起来对不上,八成是某个进程还持有已删除文件的句柄。找到 PID 后重启对应服务即可释放空间。
6.3 看内存与负载:free、uptime、vmstat
bash复制# 查看内存,-h 人类可读,-s 2 每两秒刷新
free -h
free -h -s 2
# 查看系统负载,1/5/15 分钟平均值
uptime
# 查看虚拟内存与 IO 概况
vmstat 1 5
看 free 要注意 available 这一列,它才是应用真正能用的内存。buff/cache 高不是问题,Linux 会主动用空闲内存做缓存,这部分可以回收。真正需要关注的是 available 接近 0 且 swap 使用量在涨。
vmstat 输出里重点看 r(运行队列)、si/so(交换分区换入换出)、wa(IO 等待)。wa 长期偏高说明磁盘 IO 是瓶颈,这时候继续查 CPU 意义不大,应该去看磁盘。
6.4 看磁盘:df、du
bash复制# 查看各分区使用率
df -h
# 查看 inode 使用率,小文件多时容易先满
df -i
# 查看指定目录下各子目录大小
du -h --max-depth=1 /var | sort -rh | head -10
# 查看当前目录总大小
du -sh .
df 和 du 的结果对不上是高频问题,除了上面说的已删除文件句柄,还有可能是挂载点覆盖、权限不足导致 du 跳过目录。排查顺序是:先 df -h 和 df -i 确认是空间满还是 inode 满,再 du 逐层定位,最后 lsof | grep deleted 确认是否有未释放句柄。
6.5 服务管理:systemctl、journalctl
现代发行版基本都用 systemd,服务启停和日志查看是日常动作。
bash复制# 查看服务状态,重点看 Active 和最近的日志
systemctl status nginx
# 启动、停止、重启、开机自启
sudo systemctl start nginx
sudo systemctl stop nginx
sudo systemctl restart nginx
sudo systemctl enable nginx
# 查看服务日志,-n 指定行数,-f 持续跟踪
journalctl -u nginx -n 100 --no-pager
journalctl -u nginx -f
# 按时间范围查日志
journalctl -u nginx --since "2024-01-01 10:00:00" --until "2024-01-01 12:00:00"
# 只看本次启动后的日志,排查重启后问题很有用
journalctl -u nginx -b
systemctl status 输出里会带最近十条日志,很多问题看一眼就能定位。如果服务反复重启,先看 journalctl -u 服务名 -b 找报错,再确认配置文件和端口占用,顺序不要乱。
7. 权限、用户与磁盘管理
权限问题表现为“明明文件在,就是读不了、写不进、执行不了”。这一节把 chmod、chown、umask 和用户管理讲清楚。
7.1 权限模型与 chmod
Linux 权限分三组:属主(u)、属组(g)、其他人(o),每组有读(r=4)、写(w=2)、执行(x=1)。
| 数字 | 权限 | 常见用途 |
|---|---|---|
| 644 | rw-r--r-- | 普通配置文件 |
| 600 | rw------- | 密钥、证书、含密码的配置 |
| 755 | rwxr-xr-x | 目录、可执行脚本 |
| 700 | rwx------ | 私有目录 |
| 777 | rwxrwxrwx | 不推荐,安全风险高 |
bash复制# 数字方式设置权限
chmod 644 /etc/app/config.yml
chmod 755 /data/app/start.sh
# 符号方式,给属主加执行权限
chmod u+x deploy.sh
# 递归修改目录权限
chmod -R 755 /var/www/html
这里有个常见误区:给目录加 x 权限是“能进入该目录”,加 r 是“能列出目录内容”,两者含义不同。只给 r 不给 x,ls 能看到文件名但打不开文件,这种问题在新手配置里很常见。
7.2 属主与属组:chown、chgrp
bash复制# 修改属主和属组
sudo chown app:app /data/app/config.yml
# 递归修改整个目录
sudo chown -R app:app /data/app
# 只改属组
sudo chgrp www-data /var/www/html
chown -R 在系统目录上误用后果很严重,执行前一定用 pwd 和 ls -ld 确认路径。规范做法是先 ls -ld 看当前属主,再决定改哪些。
7.3 用户与 sudo
bash复制# 创建用户并指定 home 目录
sudo useradd -m -s /bin/bash deploy
sudo passwd deploy
# 加入附加组
sudo usermod -aG docker deploy
# 查看用户所属组
id deploy
groups deploy
# 授权 sudo,推荐用 visudo 而不是直接改文件
sudo visudo
usermod -aG 里的 -a 不能省,省了会覆盖用户原有附加组,这是很常见的坑。
7.4 磁盘与挂载基础
bash复制# 查看块设备
lsblk
# 查看分区与文件系统
sudo fdisk -l
# 查看挂载情况
mount | column -t
findmnt
# 查看磁盘 IO
iostat -x 1 5
iostat 需要安装 sysstat 包。看输出时关注 %util 和 await,%util 长期接近 100% 说明磁盘已经饱和,这时候应用变慢的根因在存储层,不在应用代码。
8. 网络诊断与日志分析
网络问题的排查讲究顺序:先确认本机服务在不在,再确认端口通不通,再确认 DNS 和路由,最后才怀疑对端。
8.1 连通性:ping、traceroute、curl
bash复制# 测试基础连通性,-c 指定次数
ping -c 4 8.8.8.8
# 测试域名解析与连通性
ping -c 4 example.com
# 路由追踪,看在哪一跳开始丢包
traceroute example.com
# 部分系统用 tracepath 或 mtr
mtr -rw example.com
ping 不通不代表服务不可用,很多云环境默认禁 ICMP。判断端口通不通应该用 curl 或 telnet/nc。
bash复制# 查看 HTTP 响应头,判断服务是否正常
curl -I http://127.0.0.1:8080/health
# 带超时和详细过程,排查连接卡在哪一步
curl -v --connect-timeout 5 http://127.0.0.1:8080/health
# 测试 POST 接口
curl -X POST http://127.0.0.1:8080/api/login \
-H "Content-Type: application/json" \
-d '{"username":"test","password":"test"}'
# 只看状态码
curl -s -o /dev/null -w "%{http_code}\n" http://127.0.0.1:8080/health
curl -v 的输出会显示 DNS 解析、TCP 连接、TLS 握手、HTTP 请求各阶段耗时,是判断“慢在哪一层”的高效手段。
8.2 DNS 与端口探测
bash复制# 查询域名解析结果
dig +short example.com
# 指定 DNS 服务器查询
dig @8.8.8.8 example.com
# 查看本机 DNS 配置
cat /etc/resolv.conf
# 测试端口是否可连,nc 需要安装
nc -zv 127.0.0.1 8080
8.3 日志分析常用套路
日志分析的核心是“缩小范围”。先按时间缩小,再按关键词缩小,最后看上下文。
bash复制# 按时间范围过滤,适合大文件
sed -n '/2024-01-01 10:00/,/2024-01-01 10:30/p' /var/log/app/app.log | grep ERROR
# 统计某类错误出现次数
grep -c "Connection refused" /var/log/app/app.log
# 提取异常堆栈的前后文
grep -n "Exception" /var/log/app/app.log | tail -5
# 实时过滤关键词,排障时挂着看
tail -F /var/log/app/app.log | grep --line-buffered "ERROR"
最后这条里的 --line-buffered 很关键,不加的话管道会缓冲,导致日志不能实时输出,看起来像“卡住了”。
8.4 定时任务:crontab
日志清理、备份、巡检脚本都离不开定时任务。
bash复制# 编辑当前用户的定时任务
crontab -e
# 查看当前用户的定时任务
crontab -l
# 查看 cron 服务状态
systemctl status cron # Debian/Ubuntu
systemctl status crond # CentOS/RHEL
一个典型的清理任务写法:
bash复制# 每天凌晨 3 点清理 7 天前的日志,输出记录到独立日志
0 3 * * * /usr/bin/find /data/app/logs -name "*.log" -mtime +7 -delete >> /var/log/cleanup.log 2>&1
crontab 有几个高频坑:命令要用绝对路径,因为 cron 环境的 PATH 很精简;脚本里的相对路径会失效,因为工作目录不是你以为的那个;环境变量不会自动继承,需要显式声明;% 在 crontab 里有特殊含义,需要转义。排查 cron 不执行,先看 /var/log/cron 或 journalctl -u cron,再确认脚本手动执行是否正常。
9. 常见问题与排查方法
把前面几节的高频故障整理成一张表,遇到问题可以按图索骥。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 服务启动失败 | 配置错误、端口占用、依赖缺失 | systemctl status、journalctl -u 服务名 -n 100 |
按日志修配置,释放端口,补依赖 |
| 页面打不开 | 服务未启动、防火墙拦截、监听地址不对 | ss -lntp、curl -I、firewall-cmd --list-all |
启动服务,放行端口,改为 0.0.0.0 监听 |
| 端口被占用 | 旧进程未退出、重复启动 | ss -lntp | grep 端口、lsof -i:端口 |
确认后 kill 旧进程或换端口 |
| 磁盘满 | 日志未清理、已删除文件未释放 | df -h、df -i、du -sh /*、lsof | grep deleted |
清理日志,重启持有句柄的进程 |
| 内存不足 | 进程泄漏、缓存占用、JVM 堆过大 | free -h、ps aux --sort=-%mem、vmstat 1 |
调小堆内存,重启泄漏进程,加 swap 兜底 |
| CPU 飙高 | 死循环、频繁 GC、流量突增 | top、top -H -p PID、ps aux --sort=-%cpu |
定位线程,抓栈分析,限流或扩容 |
| 命令找不到 | PATH 未包含、包未安装 | which 命令、echo $PATH |
安装对应包,或使用绝对路径 |
| 权限不足 | 属主属组不对、目录缺 x 权限 | ls -l、id、namei -l 路径 |
chown 改属主,chmod 补权限 |
| SSH 连不上 | 网络不通、端口未开、密钥错误 | ping、nc -zv IP 22、ssh -vvv |
检查安全组、sshd 状态与密钥权限 |
| 定时任务不执行 | 路径问题、环境变量缺失、cron 未启动 | journalctl -u cron、手动执行脚本 |
用绝对路径,脚本内声明环境变量 |
sed -i 改坏配置 |
未备份、正则匹配范围过大 | diff 对比备份文件 |
从备份恢复,改为先预览再执行 |
| 中文乱码 | 编码不一致、终端设置问题 | locale、file -i 文件名 |
统一 UTF-8,设置 LANG 环境变量 |
排查有一个通用原则值得强调:先看现象,再看日志,最后看代码。跳过日志直接猜原因,往往会绕远路。而看日志的前提是知道日志在哪,这也是为什么前面要花篇幅讲 journalctl 和 tail -F。
10. 90 分钟学习路径与最佳实践
命令这东西,看一遍记不住,敲一遍才有感觉。下面给一条可执行的学习路径,按 90 分钟切分。
第一阶段,20 分钟,文件与目录。在 ~/linux-lab 里反复练 ls、cp、mv、find、tar,重点是 find 的条件组合和 tar 的打包解包。练到不看笔记能写出“查找 7 天前大于 100M 的日志并压缩”这条命令,就算过关。
第二阶段,25 分钟,文本处理。准备一份 Nginx 访问日志样本,用 grep 找错误、用 awk 统计 Top IP 和状态码分布、用 sed 做一次替换并对比备份。这一阶段的目标不是记住语法,而是形成“管道组合”的思维。
第三阶段,25 分钟,进程与资源。手动起一个占用 CPU 的进程,用 top、ps、ss、lsof 把它找出来并停掉。再造一个“删除文件但进程仍持有句柄”的场景,用 df 和 lsof | grep deleted 复现磁盘满的排查过程。这两个场景覆盖了线上最常见的两类故障。
第四阶段,20 分钟,网络与日志。用 curl 测本机服务,用 dig 查解析,用 journalctl 看服务日志,写一条 crontab 定时任务并确认执行。最后把所有命令整理成自己的速查清单。
最佳实践方面,给几条工程化建议。第一,危险命令一律先在测试环境验证,生产环境操作前记录变更内容,便于回滚。第二,配置文件修改前必须备份,命名带上日期,例如 nginx.conf.bak.20240101。第三,脚本里所有路径用绝对路径,变量加引号并做非空校验,这是避免误删误改的最低成本手段。第四,日志、数据、备份分目录管理,避免清理任务误伤业务文件。第五,长期运行的任务放在 tmux 里,避免 SSH 断线导致中断。第六,涉及用户数据、日志导出、权限变更的操作,要符合公司安全规范和数据合规要求,不要把含敏感信息的日志随意外发。第七,养成“先看再动”的习惯,find 先 -print、sed 先预览、rm 先 ls,多花十秒,少一次事故。
如果想把命令用得更顺手,建议再补三样东西:一是 bash 基础语法,包括变量、条件、循环、函数,能写出可维护的运维脚本;二是正则表达式,grep、sed、awk 的上限都取决于正则功底;三是 systemd 单元文件编写,能把自研服务规范化托管。这三样补齐之后,日常运维的绝大部分工作都能在命令行里闭环。
最后提醒一句,命令是工具,判断才是能力。同样一条 top,有人只看 CPU 百分比,有人会结合 load average、%wa、available 内存和连接数一起下结论。前者叫会用命令,后者叫会排障。这篇文章给的是前者,后者需要在真实环境里一次次复盘积累。建议把第 9 章的排查表打印出来贴在工位上,遇到问题先查表再动手,形成固定路径之后,处理故障的速度会明显不一样。
