Ubuntu 命令行实战指南
这不是一本教科书式的命令手册,而是一份面向真实场景的实战指南。当你需要部署一个服务、排查一个问题、管理一台服务器时,你会在这里找到答案。
一、命令行效率神器
1.1 历史命令快速搜索
Ctrl+R 就是其中之一:
# Ctrl+R: 反向搜索历史命令
# 输入关键词,自动匹配你用过的命令
# 再按 Ctrl+R 继续向前搜索
# Enter 执行,Ctrl+C 取消
# 查看所有历史
history
# 执行历史中的第123条命令
!123
# 执行上一条命令
!!
# 执行最近一条以 docker 开头的命令
!docker
1.2 其他效率技巧
# Ctrl+A: 跳到行首
# Ctrl+E: 跳到行末
# Ctrl+U: 删除光标前的所有内容
# Ctrl+K: 删除光标后的所有内容
# Ctrl+W: 删除光标前的一个单词
# Ctrl+L: 清屏(等同于 clear)
# Alt+.: 粘贴上一条命令的最后一个参数
# 场景: 你刚 ls /var/log/nginx/,现在想 cd 过去
cd Alt+. # 自动补全为 cd /var/log/nginx/
二、服务管理实战
2.1 场景:部署一个 Nginx 服务
第一步:安装
sudo apt update
sudo apt install nginx
第二步:检查服务状态
# 查看服务状态(最常用)
sudo systemctl status nginx
# 查看是否正在运行
sudo systemctl is-active nginx
# 查看是否开机自启
sudo systemctl is-enabled nginx
第三步:管理服务
# 启动服务
sudo systemctl start nginx
# 停止服务
sudo systemctl stop nginx
# 重启服务(配置改了后用这个)
sudo systemctl restart nginx
# 重新加载配置(不中断服务,推荐)
sudo systemctl reload nginx
# 设置开机自启
sudo systemctl enable nginx
# 取消开机自启
sudo systemctl disable nginx
# 一步到位:启用并立即启动
sudo systemctl enable --now nginx
2.2 场景:创建自己的服务
假设你写了一个 Python 程序 /home/user/myapp/app.py,想让它作为服务运行:
创建服务文件
sudo nano /etc/systemd/system/myapp.service
服务文件内容
[Unit]
Description=My Python Application
After=network.target
[Service]
Type=simple
User=user
WorkingDirectory=/home/user/myapp
ExecStart=/usr/bin/python3 /home/user/myapp/app.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
关键配置说明
After=network.target: 网络就绪后再启动Type=simple: 最常用的类型,程序前台运行Restart=always: 挂了自动重启RestartSec=10: 重启前等待 10 秒WantedBy=multi-user.target: 开机自启
启用服务
# 重新加载 systemd 配置
sudo systemctl daemon-reload
# 启动并设置自启
sudo systemctl enable --now myapp
# 查看状态
sudo systemctl status myapp
2.3 场景:找出占用端口的进程
使用 lsof(最常用)
# 查看 8080 端口被谁占用
sudo lsof -i :8080
# 输出示例:
# COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
# nginx 1234 root 6u IPv4 12345 0t0 TCP *:8080 (LISTEN)
# 只显示 PID
sudo lsof -ti :8080
# 查看某个进程打开了哪些文件
sudo lsof -p 1234
# 查看某个用户打开的所有文件
sudo lsof -u username
# 查看某个目录下被打开的文件
sudo lsof +D /var/log
# 查看某个文件被哪些进程打开
sudo lsof /var/log/nginx/access.log
# 查看所有网络连接
sudo lsof -i
# 查看 TCP 连接
sudo lsof -i tcp
# 查看 UDP 连接
sudo lsof -i udp
# 查看某个 IP 的连接
sudo lsof -i @192.168.1.1
# 持续监控某个端口(每 2 秒刷新)
watch -n 2 'sudo lsof -i :8080'
使用 netstat
# 查看所有监听的端口
sudo netstat -tlnp
# -t: TCP
# -l: 监听中的
# -n: 显示数字地址
# -p: 显示进程信息
# 查看所有连接(包括已建立的)
sudo netstat -anp
# 查看 8080 端口
sudo netstat -tlnp | grep 8080
# 统计各状态的连接数
netstat -an | awk '/^tcp/ {print $6}' | sort | uniq -c
使用 ss(更现代,推荐)
# 查看所有监听的 TCP 端口
sudo ss -tlnp
# 查看 8080 端口
sudo ss -tlnp | grep 8080
# 查看所有已建立的连接
sudo ss -tnp
# 查看连接统计
ss -s
# 查看某个进程的网络连接
sudo ss -tp | grep nginx
一步杀掉占用端口的进程
# 找到 PID 并杀掉
sudo kill $(sudo lsof -ti :8080)
# 强制杀掉
sudo kill -9 $(sudo lsof -ti :8080)
# 或者用 fuser
sudo fuser -k 8080/tcp
2.4 场景:查看服务的实时日志
systemd 服务日志(推荐)
# 查看服务日志(最近的)
sudo journalctl -u nginx
# 实时滚动查看(最常用)
sudo journalctl -u nginx -f
# 查看最近 100 行
sudo journalctl -u nginx -n 100
# 从最后开始看,并实时更新
sudo journalctl -u nginx -f -n 50
# 查看今天的日志
sudo journalctl -u nginx --since today
# 查看最近 1 小时
sudo journalctl -u nginx --since "1 hour ago"
# 查看某个时间段
sudo journalctl -u nginx --since "2024-10-20 10:00" --until "2024-10-20 11:00"
# 显示详细信息(包括完整输出)
sudo journalctl -u nginx -o verbose
# 只看错误级别的日志
sudo journalctl -u nginx -p err
# 查看多个服务的日志
sudo journalctl -u nginx -u mysql
查看应用自己的日志文件
# 实时查看日志末尾(最常用)
tail -f /var/log/nginx/access.log
# 查看最后 50 行
tail -n 50 /var/log/nginx/error.log
# 查看前 20 行
head -n 20 /var/log/nginx/access.log
# 实时查看多个日志
tail -f /var/log/nginx/access.log /var/log/nginx/error.log
# 分页查看日志(可上下翻页)
less /var/log/nginx/access.log
# 空格:下一页
# b:上一页
# /:搜索
# q:退出
查看 nohup 后台进程的日志
# 如果用了 nohup python3 app.py > app.log 2>&1 &
tail -f app.log
# 如果没指定输出文件,默认在 nohup.out
tail -f nohup.out
2.5 场景:在日志中查找特定内容
使用 grep 搜索日志
# 在日志中搜索包含 "error" 的行
grep "error" /var/log/nginx/error.log
# 忽略大小写
grep -i "error" /var/log/nginx/error.log
# 显示行号
grep -n "error" /var/log/nginx/error.log
# 显示匹配行的前后 3 行(看上下文)
grep -C 3 "error" /var/log/nginx/error.log
# 只显示前 5 行
grep -B 5 "error" /var/log/nginx/error.log
# 只显示后 5 行
grep -A 5 "error" /var/log/nginx/error.log
# 统计匹配次数
grep -c "error" /var/log/nginx/error.log
# 显示不包含某个词的行(反向搜索)
grep -v "debug" /var/log/app.log
# 使用正则表达式
grep -E "error|warning|critical" /var/log/nginx/error.log
# 递归搜索目录下所有文件
grep -r "error" /var/log/nginx/
# 只显示文件名,不显示内容
grep -l "error" /var/log/nginx/*
实时搜索日志
# 实时查看包含 "error" 的日志
tail -f /var/log/nginx/error.log | grep "error"
# 高亮显示匹配的内容
tail -f /var/log/nginx/error.log | grep --color "error"
# 实时查看 systemd 日志中的错误
sudo journalctl -u nginx -f | grep -i error
组合过滤(管道操作)
# 查找包含 "error" 但不包含 "debug" 的行
grep "error" /var/log/app.log | grep -v "debug"
# 统计每个 IP 的访问次数
cat /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn
# 查找状态码为 500 的请求
grep " 500 " /var/log/nginx/access.log
# 查看最近 1 小时的错误,并统计数量
sudo journalctl -u nginx --since "1 hour ago" | grep -i error | wc -l
使用 awk 提取特定字段
# 提取 Nginx access.log 中的 IP 地址(第一列)
awk '{print $1}' /var/log/nginx/access.log
# 提取请求的 URL(第七列)
awk '{print $7}' /var/log/nginx/access.log
# 提取状态码(第九列)
awk '{print $9}' /var/log/nginx/access.log
# 条件过滤:只显示状态码为 500 的行
awk '$9 == 500' /var/log/nginx/access.log
# 统计各个状态码的数量
awk '{print $9}' /var/log/nginx/access.log | sort | uniq -c | sort -rn
使用 sed 过滤时间范围
# 查看某个时间段的日志
sed -n '/2024-10-21 10:00/,/2024-10-21 11:00/p' /var/log/app.log
# 删除包含某个词的行后再查看
sed '/debug/d' /var/log/app.log
三、文件编辑与配置
3.1 文本编辑器选择
# nano: 最简单,适合新手
nano filename.txt
# Ctrl+O 保存, Ctrl+X 退出
# vim: 功能强大,有学习曲线
vim filename.txt
# 按 i 进入编辑模式
# 按 Esc 退出编辑模式
# 输入 :wq 保存并退出
# 输入 :q! 不保存退出
# 如果只是查看文件
cat filename.txt
less filename.txt # 可以翻页,q 退出
3.2 场景:编辑 Nginx 配置
# 编辑主配置
sudo nano /etc/nginx/nginx.conf
# 编辑站点配置
sudo nano /etc/nginx/sites-available/default
# 测试配置是否有语法错误(重要!)
sudo nginx -t
# 配置正确后重新加载
sudo systemctl reload nginx
3.3 场景:修改环境变量
# 临时修改(关闭终端就失效)
export PATH=$PATH:/opt/myapp/bin
# 永久修改(当前用户)
nano ~/.bashrc
# 在文件末尾添加:
# export PATH=$PATH:/opt/myapp/bin
# 使配置生效
source ~/.bashrc
# 或者重新登录
四、文件与目录操作
4.1 查找文件
# 按名称查找
find /var/log -name "*.log"
# 查找最近 7 天修改的文件
find /var/log -mtime -7
# 查找大于 100M 的文件
find /var/log -size +100M
# 在文件内容中搜索(递归搜索目录)
grep -r "error" /var/log/nginx/
# 忽略大小写
grep -ri "error" /var/log/nginx/
# 显示行号
grep -rn "error" /var/log/nginx/
4.2 磁盘空间管理
# 查看磁盘使用情况
df -h
# 查看当前目录下各子目录的大小
du -h --max-depth=1
# 找出最大的 10 个文件
du -ah /var/log | sort -rh | head -10
# 查看某个目录的总大小
du -sh /var/log/nginx/
4.3 文件权限与所有者
# 查看详细信息
ls -lh
# 修改所有者
sudo chown user:group filename
# 递归修改目录
sudo chown -R user:group /var/www/html
# 修改权限(755: 所有者全权限,其他人读+执行)
chmod 755 script.sh
# 让脚本可执行
chmod +x script.sh
# 常用权限:
# 644: 文件(所有者读写,其他人只读)
# 755: 目录或可执行文件
# 600: 私密文件(如 SSH 密钥)
五、进程管理
5.1 查看进程
# 查看所有进程
ps aux
# 查看特定进程(比如 nginx)
ps aux | grep nginx
# 实时查看进程(类似 Windows 任务管理器)
top
# 或更友好的
htop # 需要先安装: sudo apt install htop
# 按内存排序查看前 10 个进程
ps aux --sort=-%mem | head -10
# 按 CPU 排序
ps aux --sort=-%cpu | head -10
5.2 后台运行与进程管理
场景:需要运行一个长期任务,退出 SSH 后还要继续运行
# 方法一:使用 nohup(最常用)
nohup python3 app.py > app.log 2>&1 &
# nohup: 忽略挂断信号
# > app.log: 标准输出重定向到文件
# 2>&1: 错误输出也重定向到同一文件
# &: 后台运行
# 查看 nohup 进程输出
tail -f app.log
# 方法二:使用 screen(可以随时重新连接)
screen -S myapp
python3 app.py
# 按 Ctrl+A 然后按 D 断开(进程继续运行)
# 重新连接到 screen
screen -r myapp
# 查看所有 screen 会话
screen -ls
# 方法三:使用 tmux(更现代的 screen)
tmux new -s myapp
python3 app.py
# 按 Ctrl+B 然后按 D 断开
# 重新连接
tmux attach -t myapp
# 查看 tmux 会话
tmux ls
查看后台任务
# 查看当前终端的后台任务
jobs
# 查看后台任务的 PID
jobs -l
# 把后台任务调到前台
fg %1 # 1 是任务编号
# 把前台任务暂停并放到后台
Ctrl+Z # 先暂停
bg # 再后台运行
# 杀掉后台任务
kill %1
六、网络调试与诊断
6.1 测试连接
# 测试网络连通性
ping google.com
ping -c 4 google.com # 只 ping 4 次
# 测试端口是否开放
telnet example.com 80
# 或用 nc(netcat,更强大)
nc -zv example.com 80
# -z: 扫描模式,不发送数据
# -v: 详细输出
# 扫描端口范围
nc -zv example.com 80-100
# 监听端口(测试用)
nc -l 8080 # 在一个终端监听
nc localhost 8080 # 在另一个终端连接
# 测试 UDP 端口
nc -zvu example.com 53
6.2 HTTP 请求测试
# 基本 GET 请求
curl http://localhost:8080
# 查看完整的请求和响应头
curl -v http://localhost:8080
# 只看响应头
curl -I http://localhost:8080
# POST 请求
curl -X POST -d "key=value" http://localhost:8080/api
# POST JSON 数据
curl -X POST \
-H "Content-Type: application/json" \
-d '{"name":"test","age":25}' \
http://localhost:8080/api
# 带认证的请求
curl -u username:password http://localhost:8080/api
# 带 Cookie
curl -b "session=abc123" http://localhost:8080
# 保存 Cookie
curl -c cookies.txt http://localhost:8080/login
# 使用保存的 Cookie
curl -b cookies.txt http://localhost:8080/dashboard
# 下载文件
curl -O https://example.com/file.zip
# 指定保存的文件名
curl -o myfile.zip https://example.com/file.zip
# 断点续传
curl -C - -O https://example.com/largefile.zip
# 限速下载(100KB/s)
curl --limit-rate 100K -O https://example.com/file.zip
# 跟随重定向
curl -L http://example.com
# 测试接口响应时间
curl -w "@-" -o /dev/null -s http://localhost:8080 <<'EOF'
time_namelookup: %{time_namelookup}\n
time_connect: %{time_connect}\n
time_appconnect: %{time_appconnect}\n
time_redirect: %{time_redirect}\n
time_pretransfer: %{time_pretransfer}\n
time_starttransfer: %{time_starttransfer}\n
----------\n
time_total: %{time_total}\n
EOF
6.3 DNS 查询
# 查询域名的 IP
nslookup google.com
# 更详细的 DNS 查询
dig google.com
# 只显示 IP 地址
dig +short google.com
# 查询 MX 记录(邮件服务器)
dig google.com MX
# 查询 DNS 记录类型
dig google.com ANY
# 指定 DNS 服务器查询
dig @8.8.8.8 google.com
# 反向查询(IP 查域名)
dig -x 8.8.8.8
# 使用 host 命令
host google.com
6.4 路由追踪
# 追踪到目标的网络路径
traceroute google.com
# 或用 tracepath(不需要 root)
tracepath google.com
# 使用 mtr(更好的追踪工具)
mtr google.com
# 实时显示每一跳的延迟和丢包率
6.5 网络连接查看
# 查看所有网络连接
ss -tunapr
# 查看建立的连接
ss -tn state established
# 查看监听的端口
ss -tln
# 查看哪些进程连接到远程服务器
ss -tnp | grep 443
# 统计连接状态
ss -tan | awk '{print $1}' | sort | uniq -c
# 查看网络接口
ip addr show
# 查看路由表
ip route show
# 查看 ARP 表
ip neigh show
6.6 抓包分析
# 安装 tcpdump
sudo apt install tcpdump
# 抓取所有网卡的包
sudo tcpdump
# 抓取指定网卡
sudo tcpdump -i eth0
# 抓取指定端口
sudo tcpdump port 80
# 抓取指定 IP
sudo tcpdump host 192.168.1.100
# 抓取并保存到文件
sudo tcpdump -i eth0 -w capture.pcap
# 读取抓包文件
sudo tcpdump -r capture.pcap
# 只抓取 HTTP 请求
sudo tcpdump -i eth0 -A 'tcp port 80 and (tcp[((tcp[12:1] & 0xf0) >> 2):4] = 0x47455420)'
# 抓取特定数量的包
sudo tcpdump -c 100
# 显示详细信息
sudo tcpdump -v port 80
6.7 防火墙管理
# 查看防火墙状态
sudo ufw status
# 查看详细规则(带编号)
sudo ufw status numbered
# 允许某个端口
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw allow 22/tcp # SSH,小心别把自己锁外面
# 允许端口范围
sudo ufw allow 6000:6010/tcp
# 允许特定 IP 访问
sudo ufw allow from 192.168.1.100
# 允许特定 IP 访问特定端口
sudo ufw allow from 192.168.1.100 to any port 22
# 拒绝连接
sudo ufw deny 23/tcp
# 删除规则(按编号)
sudo ufw delete 3
# 删除规则(按规则内容)
sudo ufw delete allow 80/tcp
# 启用防火墙
sudo ufw enable
# 禁用防火墙
sudo ufw disable
# 重置所有规则
sudo ufw reset
# 查看应用配置文件
sudo ufw app list
# 使用应用配置
sudo ufw allow 'Nginx Full'
6.8 网速测试
# 安装 speedtest
sudo apt install speedtest-cli
# 测试网速
speedtest-cli
# 只测试下载速度
speedtest-cli --no-upload
# 用字节显示(而不是比特)
speedtest-cli --bytes
# 使用 iperf3 测试局域网速度
# 服务器端:
iperf3 -s
# 客户端:
iperf3 -c 192.168.1.100
七、系统监控与性能分析
7.1 资源使用监控
# 查看内存使用
free -h
# 持续监控内存(每 2 秒刷新)
watch -n 2 free -h
# 查看内存详细信息
cat /proc/meminfo
# 查看 CPU 信息
lscpu
# 查看 CPU 使用率
top
# 按 1: 显示每个 CPU 核心
# 按 P: 按 CPU 排序
# 按 M: 按内存排序
# 按 k: 杀掉进程
# 更友好的 top(需安装)
htop
# F2: 设置
# F3: 搜索进程
# F4: 过滤
# F5: 树状显示
# F9: 杀进程
# F10: 退出
# 查看系统负载
uptime
# 显示: 运行时间, 用户数, 1/5/15 分钟平均负载
# 查看负载详情
w
7.2 磁盘 I/O 监控
# 实时查看磁盘 I/O
iostat -x 2
# 每 2 秒刷新一次
# 查看哪些进程在读写磁盘
sudo iotop
# 只显示正在读写的进程
sudo iotop -o
# 查看磁盘读写统计
sudo iotop -a
# 使用 pidstat 查看进程 I/O
pidstat -d 2
7.3 进程详细分析
# 查看进程树
pstree
# 查看某个进程的树
pstree -p 1234
# 查看进程详细信息
ps aux | grep nginx
# 查看进程的线程
ps -T -p 1234
# 查看进程打开的文件描述符数量
lsof -p 1234 | wc -l
# 查看进程的环境变量
cat /proc/1234/environ | tr '\0' '\n'
# 查看进程的命令行参数
cat /proc/1234/cmdline
# 查看进程的内存映射
cat /proc/1234/maps
# 查看进程的资源限制
cat /proc/1234/limits
# 使用 pidstat 监控进程
pidstat -p 1234 2
# 每 2 秒显示进程 1234 的统计
7.4 系统日志查看
# 查看系统日志
sudo tail -f /var/log/syslog
# 查看认证日志(登录记录)
sudo tail -f /var/log/auth.log
# 查看内核日志
dmesg
# 实时查看内核日志
dmesg -w
# 查看内核错误
dmesg --level=err
# 查看最近的启动日志
journalctl -b
# 查看上一次启动的日志
journalctl -b -1
# 查看所有启动记录
journalctl --list-boots
# 查看内核日志
journalctl -k
# 查看某个时间后的所有日志
journalctl --since "2024-10-20 10:00"
# 查看特定优先级的日志
journalctl -p err
# 优先级: emerg, alert, crit, err, warning, notice, info, debug
# 查看磁盘使用情况
journalctl --disk-usage
# 清理旧日志(保留最近 100MB)
sudo journalctl --vacuum-size=100M
# 清理 7 天前的日志
sudo journalctl --vacuum-time=7d
7.5 性能分析工具
# 查看系统调用
strace ls
# 跟踪 ls 命令的系统调用
# 跟踪正在运行的进程
sudo strace -p 1234
# 统计系统调用
strace -c ls
# 查看进程打开的文件
sudo strace -e open,openat ls
# 使用 ltrace 跟踪库函数调用
ltrace ls
# 使用 perf 进行性能分析(需安装)
sudo perf top
# 实时显示 CPU 热点
# 记录性能数据
sudo perf record -a -g sleep 10
# 查看性能报告
sudo perf report
# 查看系统瓶颈
vmstat 2
# 每 2 秒显示一次虚拟内存统计
# 查看 CPU 统计
mpstat 2
7.6 网络流量监控
# 实时监控网络流量
sudo iftop
# 按 t: 切换显示模式
# 按 h: 帮助
# 按 q: 退出
# 按连接显示流量
sudo iftop -P
# 监控特定网卡
sudo iftop -i eth0
# 使用 nethogs 按进程监控流量
sudo nethogs
# 监控特定网卡
sudo nethogs eth0
# 使用 vnstat 统计流量(需先配置)
vnstat
vnstat -d # 按天统计
vnstat -m # 按月统计
vnstat -h # 按小时统计
八、实用技巧合集
8.1 批量操作
# 批量重命名(把所有 .txt 改成 .md)
for file in *.txt; do mv "$file" "${file%.txt}.md"; done
# 批量删除某类文件
find . -name "*.log" -delete
# 批量修改权限
find /var/www -type f -exec chmod 644 {} \;
find /var/www -type d -exec chmod 755 {} \;
8.2 压缩与解压
# 打包并压缩
tar -czf archive.tar.gz /path/to/directory
# 解压
tar -xzf archive.tar.gz
# 只查看压缩包内容,不解压
tar -tzf archive.tar.gz
# zip 格式
zip -r archive.zip /path/to/directory
unzip archive.zip
8.3 定时任务
# 编辑定时任务
crontab -e
# 常用格式:
# * * * * * command
# 分 时 日 月 周
# 示例:每天凌晨 2 点备份
0 2 * * * /home/user/backup.sh
# 每 5 分钟执行一次
*/5 * * * * /home/user/check.sh
# 查看当前的定时任务
crontab -l
8.4 命令行快捷操作
# 快速创建多级目录
mkdir -p /path/to/nested/directory
# 同时创建文件和父目录
mkdir -p /path/to && touch /path/to/file.txt
# 切换到上一个目录
cd -
# 快速备份文件
cp file.conf{,.bak} # 等同于 cp file.conf file.conf.bak
# 清空文件内容
> file.txt
# 快速生成大文件(测试用)
dd if=/dev/zero of=test.img bs=1M count=100
九、故障排查实战手册
9.1 服务启动失败排查
完整排查流程:
# 第一步: 查看服务状态
sudo systemctl status servicename
# 看输出的错误信息和退出码
# 第二步: 查看详细日志
sudo journalctl -u servicename -n 100 --no-pager
# 看最近 100 行日志,找错误信息
# 第三步: 实时查看启动过程
sudo journalctl -u servicename -f
# 在另一个终端尝试启动服务
sudo systemctl start servicename
# 第四步: 检查配置文件语法
# Nginx:
sudo nginx -t
# Apache:
sudo apache2ctl configtest
# MySQL:
sudo mysqld --validate-config
# 第五步: 检查端口占用
sudo lsof -i :80
sudo ss -tlnp | grep :80
# 第六步: 检查文件权限
ls -l /etc/nginx/nginx.conf
ls -ld /var/www/html
# 第七步: 检查 SELinux/AppArmor
sudo aa-status # AppArmor
getenforce # SELinux
# 第八步: 手动运行程序看错误
# 找到服务的 ExecStart 命令
sudo systemctl cat servicename
# 手动执行那个命令
# 第九步: 查看系统日志
sudo tail -n 50 /var/log/syslog | grep servicename
# 第十步: 检查依赖服务
sudo systemctl list-dependencies servicename
常见错误及解决:
# 错误: Address already in use
# 解决: 杀掉占用端口的进程
sudo lsof -ti :80 | xargs sudo kill -9
# 错误: Permission denied
# 解决: 检查文件权限和所有者
sudo chown -R www-data:www-data /var/www/html
sudo chmod -R 755 /var/www/html
# 错误: No such file or directory
# 解决: 创建缺失的目录
sudo mkdir -p /var/log/myapp
sudo chown myuser:myuser /var/log/myapp
# 错误: Failed to start (timeout)
# 解决: 增加启动超时时间
# 编辑服务文件,添加:
# TimeoutStartSec=300
9.2 磁盘空间不足排查
# 第一步: 查看磁盘使用情况
df -h
# 第二步: 找出占用空间最大的目录
sudo du -h / --max-depth=1 2>/dev/null | sort -rh | head -10
# 第三步: 深入查看大目录
sudo du -h /var --max-depth=1 | sort -rh | head -10
# 第四步: 找出最大的文件
sudo find / -type f -size +100M -exec ls -lh {} \; 2>/dev/null | awk '{print $5, $9}' | sort -rh | head -20
# 第五步: 查看已删除但仍被占用的文件
sudo lsof | grep deleted | sort -k7 -rn
# 第六步: 清理方案
# 清理包管理器缓存
sudo apt clean
sudo apt autoremove
# 清理日志(保留最近 100MB)
sudo journalctl --vacuum-size=100M
# 清理旧日志文件
sudo find /var/log -name "*.gz" -delete
sudo find /var/log -name "*.1" -delete
# 清理 Docker(如果使用)
docker system prune -a
# 清理 snap 旧版本
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read name revision; do sudo snap remove "$name" --revision="$revision"; done
# 清理临时文件
sudo rm -rf /tmp/*
sudo rm -rf /var/tmp/*
# 清理缩略图缓存
rm -rf ~/.cache/thumbnails/*
# 第七步: 找出僵尸文件(已删除但进程仍打开)
sudo lsof +L1
# 需要重启相关进程来释放空间
9.3 网络不通排查
# 第一步: 检查网卡状态
ip addr show
# 确认网卡有 IP 地址
# 第二步: 检查网卡是否 up
ip link show
# 如果显示 DOWN:
sudo ip link set eth0 up
# 第三步: 检查本机网络
ping 127.0.0.1
# 第四步: 检查网关
ip route show
# 记下网关 IP,然后 ping
ping 192.168.1.1
# 第五步: 检查 DNS
cat /etc/resolv.conf
# 测试 DNS 解析
nslookup google.com
# 如果失败,尝试:
echo "nameserver 8.8.8.8" | sudo tee -a /etc/resolv.conf
# 第六步: 测试外网连通性
ping 8.8.8.8
# 如果通,说明网络正常,DNS 有问题
# 第七步: 检查防火墙规则
sudo iptables -L -n
sudo ufw status
# 第八步: 检查路由表
ip route show
netstat -rn
# 第九步: 追踪路由
traceroute google.com
mtr google.com
# 第十步: 检查网络服务
sudo systemctl status NetworkManager
sudo systemctl status systemd-networkd
9.4 进程僵死/卡死排查
# 第一步: 找到进程
ps aux | grep processname
# 第二步: 查看进程状态
ps -o pid,stat,cmd -p 1234
# STAT 含义:
# D: 不可中断睡眠(通常是 I/O)
# R: 运行中
# S: 睡眠
# T: 停止
# Z: 僵尸进程
# 第三步: 查看进程在做什么
sudo strace -p 1234
# 第四步: 查看进程的文件操作
sudo lsof -p 1234
# 第五步: 查看进程的系统调用
sudo cat /proc/1234/stack
# 第六步: 生成进程堆栈
sudo gdb -p 1234 -batch -ex "thread apply all bt"
# 第七步: 查看进程的 CPU 使用
top -p 1234
# 第八步: 尝试正常终止
kill -15 1234
# 等待 10 秒
# 第九步: 强制终止
kill -9 1234
# 如果是僵尸进程(Z 状态):
# 找到父进程
ps -o ppid= -p 1234
# 杀掉父进程
sudo kill -9 <ppid>
9.5 内存不足/泄漏排查
# 第一步: 查看内存使用
free -h
# 看 available 这一列
# 第二步: 找出内存占用最大的进程
ps aux --sort=-%mem | head -10
# 第三步: 查看进程的详细内存
sudo pmap -x 1234
# 第四步: 实时监控内存变化
watch -n 1 'ps aux --sort=-%mem | head -10'
# 第五步: 查看内存映射
sudo cat /proc/1234/smaps
# 第六步: 检查是否有内存泄漏
# 持续观察某个进程的内存占用
while true; do
ps -o pid,vsz,rss,cmd -p 1234
sleep 5
done
# 第七步: 查看 OOM 杀进程记录
sudo dmesg | grep -i "killed process"
sudo journalctl -k | grep -i "killed process"
# 第八步: 临时释放缓存(不推荐,除非紧急)
sudo sync
echo 3 | sudo tee /proc/sys/vm/drop_caches
9.6 高 CPU 占用排查
# 第一步: 找出 CPU 占用高的进程
top
# 按 P 按 CPU 排序
# 或者:
ps aux --sort=-%cpu | head -10
# 第二步: 查看进程的线程
top -H -p 1234
# 找出哪个线程占用高
# 第三步: 转换线程 ID 为十六进制
printf "%x\n" 1234
# 第四步: 查看线程堆栈
sudo cat /proc/1234/task/*/stack
# 第五步: 使用 perf 分析
sudo perf top -p 1234
# 或者记录 10 秒的性能数据
sudo perf record -p 1234 -g sleep 10
sudo perf report
# 第六步: 查看进程的系统调用
sudo strace -c -p 1234
# 第七步: 检查是否是死循环
sudo strace -p 1234 2>&1 | head -100
9.7 SSH 登录问题排查
# 场景一: 连接超时
# 检查网络连通性
ping server_ip
# 检查端口是否开放
nc -zv server_ip 22
# 检查防火墙
sudo ufw status
# 场景二: Permission denied
# 检查 SSH 服务状态
sudo systemctl status ssh
# 查看 SSH 日志
sudo tail -f /var/log/auth.log
# 检查 SSH 配置
sudo nano /etc/ssh/sshd_config
# 确认:
# PermitRootLogin yes/no
# PasswordAuthentication yes/no
# PubkeyAuthentication yes
# 重启 SSH 服务
sudo systemctl restart ssh
# 场景三: 密钥认证失败
# 检查密钥权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
# 检查密钥内容
cat ~/.ssh/authorized_keys
# 在客户端测试连接
ssh -v user@server_ip
# 看详细输出找问题
9.8 文件系统问题排查
# 文件系统只读
# 查看挂载状态
mount | grep "on / "
# 重新挂载为读写
sudo mount -o remount,rw /
# 检查文件系统错误
sudo fsck /dev/sda1
# 注意: 必须先卸载分区或在救援模式下运行
# 查看磁盘健康状态
sudo smartctl -a /dev/sda
# 查看 I/O 错误
dmesg | grep -i error
sudo journalctl -k | grep -i "I/O error"
# 查看文件系统 inode 使用
df -i
# inode 用完的解决:
# 找出文件数量最多的目录
sudo find / -xdev -type f | cut -d "/" -f 2 | sort | uniq -c | sort -rn | head -10
# 删除不需要的小文件
sudo find /tmp -type f -delete
9.9 快速诊断脚本
创建一个一键诊断脚本:
#!/bin/bash
# system_check.sh - 系统快速诊断
echo "========== 系统基本信息 =========="
uname -a
uptime
echo -e "\n========== CPU 使用 TOP 5 =========="
ps aux --sort=-%cpu | head -6
echo -e "\n========== 内存使用 TOP 5 =========="
ps aux --sort=-%mem | head -6
echo -e "\n========== 内存状态 =========="
free -h
echo -e "\n========== 磁盘使用 =========="
df -h
echo -e "\n========== 磁盘 I/O =========="
iostat -x 1 2 | tail -n +4
echo -e "\n========== 网络连接统计 =========="
ss -s
echo -e "\n========== 监听端口 =========="
ss -tlnp
echo -e "\n========== 最近的系统错误 =========="
journalctl -p err -n 10 --no-pager
echo -e "\n========== 最近登录记录 =========="
last -n 10
echo -e "\n========== 失败的服务 =========="
systemctl --failed
使用:
chmod +x system_check.sh
sudo ./system_check.sh
十、进阶技巧与最佳实践
10.1 别名(Alias)提高效率
设置常用别名:
# 编辑 bash 配置
nano ~/.bashrc
# 在文件末尾添加:
alias ll='ls -alh'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'
alias grep='grep --color=auto'
# 常用系统命令别名
alias update='sudo apt update && sudo apt upgrade'
alias install='sudo apt install'
alias remove='sudo apt remove'
alias search='apt search'
# 快速查看日志
alias syslog='sudo tail -f /var/log/syslog'
alias authlog='sudo tail -f /var/log/auth.log'
# 网络相关
alias ports='sudo netstat -tulnp'
alias listening='sudo lsof -i -P -n | grep LISTEN'
# 进程相关
alias psmem='ps aux --sort=-%mem | head'
alias pscpu='ps aux --sort=-%cpu | head'
# Docker 相关(如果使用)
alias dps='docker ps'
alias dpa='docker ps -a'
alias di='docker images'
alias dlog='docker logs -f'
# Git 相关
alias gs='git status'
alias ga='git add'
alias gc='git commit'
alias gp='git push'
alias gl='git log --oneline'
# 使别名生效
source ~/.bashrc
# 查看所有别名
alias
# 临时禁用别名(使用原始命令)
\ls # 前面加反斜杠
10.2 环境变量管理
# 查看所有环境变量
env
printenv
# 查看特定变量
echo $PATH
echo $HOME
# 临时设置变量(当前 shell 有效)
export MY_VAR="value"
# 永久设置(当前用户)
nano ~/.bashrc
# 添加:
export MY_VAR="value"
export PATH=$PATH:/opt/myapp/bin
# 永久设置(所有用户)
sudo nano /etc/environment
# 添加:
MY_VAR="value"
# 使变量生效
source ~/.bashrc
# 删除变量
unset MY_VAR
10.3 输入输出重定向
# 标准输出重定向
ls > output.txt # 覆盖
ls >> output.txt # 追加
# 标准错误重定向
command 2> error.txt
# 同时重定向输出和错误
command > output.txt 2>&1
command &> output.txt # 简写
# 分别重定向
command > output.txt 2> error.txt
# 丢弃输出
command > /dev/null 2>&1
# 输入重定向
command < input.txt
# Here Document
cat << EOF > file.txt
line 1
line 2
EOF
# Here String
grep "pattern" <<< "test string"
10.4 管道与命令组合
# 管道: 前一个命令的输出作为后一个的输入
ps aux | grep nginx | awk '{print $2}'
# 统计行数
ps aux | wc -l
# 排序并去重
cat file.txt | sort | uniq
# 计数重复行
cat file.txt | sort | uniq -c
# xargs: 将标准输入转为命令参数
find . -name "*.tmp" | xargs rm
find . -name "*.log" -print0 | xargs -0 rm # 处理文件名有空格的情况
# tee: 同时输出到屏幕和文件
ls -la | tee output.txt
# 命令替换
echo "Today is $(date)"
echo "Files: $(ls | wc -l)"
# 命令组合
cd /var/log && ls -lh # 前面成功才执行后面
cd /nonexist || echo "Failed" # 前面失败才执行后面
mkdir test && cd test # 常用组合
10.5 循环与条件
在命令行中使用循环:
# for 循环
for i in {1..5}; do echo "Number $i"; done
# 遍历文件
for file in *.txt; do echo "Processing $file"; done
# while 循环
i=1; while [ $i -le 5 ]; do echo $i; ((i++)); done
# 批量重命名
for file in *.txt; do mv "$file" "${file%.txt}.md"; done
# 批量下载
for i in {1..10}; do wget "http://example.com/file$i.zip"; done
# 条件判断
if [ -f file.txt ]; then echo "File exists"; else echo "Not found"; fi
# 检查目录
if [ -d /var/log ]; then cd /var/log; fi
# 检查命令是否存在
if command -v docker &> /dev/null; then echo "Docker installed"; fi
10.6 脚本调试
# 显示执行的每一条命令
bash -x script.sh
# 在脚本开头添加
#!/bin/bash
set -x # 显示执行的命令
set -e # 遇到错误立即退出
set -u # 使用未定义变量时报错
set -o pipefail # 管道中任何命令失败都算失败
# 或者一行搞定
set -euxo pipefail
# 调试特定部分
set -x
# 要调试的代码
set +x
# 使用 shellcheck 检查脚本
sudo apt install shellcheck
shellcheck script.sh
10.7 文本处理神器
sed 实用示例:
# 替换文本(不修改原文件)
sed 's/old/new/' file.txt
# 替换所有匹配(不只是第一个)
sed 's/old/new/g' file.txt
# 直接修改文件
sed -i 's/old/new/g' file.txt
# 删除空行
sed '/^$/d' file.txt
# 删除包含某个词的行
sed '/pattern/d' file.txt
# 在第 3 行后插入内容
sed '3a\New line' file.txt
# 替换第 5 行
sed '5c\New content' file.txt
# 只处理第 2 到第 5 行
sed '2,5s/old/new/g' file.txt
awk 实用示例:
# 打印第一列
awk '{print $1}' file.txt
# 打印第一和第三列
awk '{print $1, $3}' file.txt
# 使用不同的分隔符
awk -F ':' '{print $1}' /etc/passwd
# 条件过滤
awk '$3 > 100' file.txt
# 计算总和
awk '{sum += $1} END {print sum}' file.txt
# 统计行数
awk 'END {print NR}' file.txt
# 格式化输出
awk '{printf "%-10s %s\n", $1, $2}' file.txt
# Nginx 日志分析: 统计状态码
awk '{print $9}' access.log | sort | uniq -c | sort -rn
# 统计 IP 访问量
awk '{print $1}' access.log | sort | uniq -c | sort -rn | head -10
# 计算平均响应时间
awk '{sum+=$NF} END {print sum/NR}' time.log
10.8 定时任务进阶
# 编辑 crontab
crontab -e
# Crontab 格式:
# ┌─────── 分钟 (0-59)
# │ ┌───── 小时 (0-23)
# │ │ ┌─── 日期 (1-31)
# │ │ │ ┌─ 月份 (1-12)
# │ │ │ │ ┌ 星期 (0-6, 0=周日)
# │ │ │ │ │
# * * * * * command
# 实用示例:
# 每分钟执行
* * * * * /path/to/script.sh
# 每 5 分钟
*/5 * * * * /path/to/script.sh
# 每小时的第 30 分钟
30 * * * * /path/to/script.sh
# 每天凌晨 2 点
0 2 * * * /path/to/script.sh
# 每周一上午 9 点
0 9 * * 1 /path/to/script.sh
# 每月 1 号凌晨 3 点
0 3 1 * * /path/to/script.sh
# 工作日早上 8 点
0 8 * * 1-5 /path/to/script.sh
# 重定向输出和错误
0 2 * * * /path/to/script.sh >> /var/log/backup.log 2>&1
# 设置环境变量
0 2 * * * export PATH=/usr/local/bin:$PATH && /path/to/script.sh
# 查看 cron 日志
sudo tail -f /var/log/syslog | grep CRON
# 系统级定时任务(在 /etc/cron.d/ 创建文件)
sudo nano /etc/cron.d/myapp
# 格式: 分 时 日 月 周 用户 命令
0 2 * * * root /path/to/script.sh
10.9 SSH 进阶技巧
# SSH 密钥认证
ssh-keygen -t rsa -b 4096 -C "[email protected]"
ssh-copy-id user@server
# SSH 配置文件(~/.ssh/config)
nano ~/.ssh/config
# 内容示例:
Host myserver
HostName 192.168.1.100
User ubuntu
Port 22
IdentityFile ~/.ssh/id_rsa
# 使用: ssh myserver
# SSH 端口转发
# 本地转发: 访问本地 8080 -> 转发到远程 80
ssh -L 8080:localhost:80 user@server
# 远程转发: 远程访问 8080 -> 转发到本地 80
ssh -R 8080:localhost:80 user@server
# 动态转发(SOCKS 代理)
ssh -D 1080 user@server
# 保持连接
# 在 ~/.ssh/config 添加:
Host *
ServerAliveInterval 60
ServerAliveCountMax 3
# SSH 跳板机
ssh -J jumphost targethost
# 后台运行 SSH 连接
ssh -fN -L 8080:localhost:80 user@server
# SCP 文件传输
scp file.txt user@server:/path/to/destination
scp -r directory/ user@server:/path/
scp user@server:/path/file.txt ./
# rsync 同步(更强大)
rsync -avz source/ user@server:/destination/
rsync -avz --delete source/ user@server:/destination/ # 删除目标多余文件
rsync -avz -e "ssh -p 2222" source/ user@server:/dest/ # 指定端口
10.10 实用单行命令
# 快速启动 HTTP 服务器(分享文件)
python3 -m http.server 8000
# 生成随机密码
openssl rand -base64 16
# 查看哪些用户在线
w
who
# 查看登录历史
last
last -10 # 最近 10 次
# 查看失败的登录尝试
sudo lastb
# 显示文件的十六进制
xxd file.bin
# 对比两个文件
diff file1.txt file2.txt
diff -u file1.txt file2.txt # 统一格式
vimdiff file1.txt file2.txt # 可视化对比
# 批量替换文件内容
find . -name "*.txt" -exec sed -i 's/old/new/g' {} \;
# 查找并删除空目录
find . -type d -empty -delete
# 查看文件的创建/修改时间
stat file.txt
# 快速备份文件
cp important.conf{,.backup}
# 创建目录并进入
mkdir -p project/src && cd $_
# 上一个命令的最后一个参数
echo $_
# 清空文件但保留文件
> file.txt
# 比较两个目录
diff -rq dir1/ dir2/
# 监控文件变化
watch -d -n 1 'ls -lh file.txt'
# 查看进程树
pstree -p
# 在后台解压大文件
nohup tar -xzf large.tar.
命令行的学习是一个持续的过程,不需要一次记住所有命令。建议:
- 收藏这篇文章,遇到问题时快速查找
- 用到什么学什么,不要死记硬背
- 使用 Tab 键自动补全,提高效率减少错误
- 建立自己的命令片段库,把常用的命令保存到笔记里
善用 --help 和 man:大部分命令都有帮助文档
nginx --helpman systemctl
最重要的是:不要怕敲错命令,Linux 不会轻易让你搞坏系统(除非你 sudo rm -rf /)。多练习,你很快就能熟练掌握这些工具。