Linux 新手村Linux 新手村
🏠 首页
📖 教程
  • Linux 官网
  • Ubuntu 官网
  • CentOS 官网
🏠 首页
📖 教程
  • Linux 官网
  • Ubuntu 官网
  • CentOS 官网
  • 🚀 入门篇 - 欢迎来到 Linux 世界

    • 📚 长安的教程导航
    • 🐧 什么是 Linux?
    • 💿 安装 Linux
    • 🎉 首次开机
  • 🎯 基础篇 - 必备生存技能

    • ⌨️ 基础命令
    • 🗂️ 文件系统
    • 📝 文件操作
    • 👥 用户与权限
  • ⚔️ 进阶篇 - 成为高手之路

    • ⚔️ Vim 编辑器
    • 🤖 Shell 脚本
    • ⚙️ 进程与服务
    • 🌐 网络基础
  • 🏆 高级篇 - 突破自我

    • 💡 高级技巧
    • 🔧 故障排查
    • 🎭 日常案例与血泪教训

🎭 日常案例与血泪教训

大家好,我是长安!这是最后一章了,长安把自己工作中的真实案例和血泪教训分享给大家,希望你们能少走弯路。

🎯 本章目标

跟着长安读完这一章,你将收获:

  • 真实工作场景中的 Linux 使用案例
  • 长安和前人踩过的坑,让你少走弯路
  • 一些保命的好习惯

🏢 日常使用案例

案例一:部署一个简单网站

场景:老板说明天要上线一个活动页面,给你一台 Linux 服务器。

# 1. 连接服务器
ssh root@your-server-ip

# 2. 安装 Nginx
sudo apt update
sudo apt install nginx -y

# 3. 确认 Nginx 运行
sudo systemctl status nginx
curl localhost

# 4. 上传网站文件
# 方法一:scp
scp -r ./website/* root@your-server:/var/www/html/

# 方法二:rsync(推荐,支持断点续传)
rsync -avz --progress ./website/ root@your-server:/var/www/html/

# 5. 设置权限
sudo chown -R www-data:www-data /var/www/html/
sudo chmod -R 755 /var/www/html/

# 6. 配置 Nginx(如果需要自定义配置)
sudo vim /etc/nginx/sites-available/default

# 7. 检查配置并重载
sudo nginx -t
sudo systemctl reload nginx

踩坑点:

  • 忘记开放防火墙 80 端口 → sudo ufw allow 80
  • 文件权限不对导致 403 错误 → 检查 chown 和 chmod
  • 忘记重载配置 → nginx -t 测试后一定要 reload

案例二:日志分析找问题

场景:网站访问变慢,需要分析日志找原因。

# 1. 查看实时访问日志
tail -f /var/log/nginx/access.log

# 2. 统计今天访问量
cat /var/log/nginx/access.log | wc -l

# 3. 统计访问最多的 IP(找出是否有人在攻击)
cat /var/log/nginx/access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# 4. 统计访问最多的 URL
cat /var/log/nginx/access.log | awk '{print $7}' | sort | uniq -c | sort -rn | head -20

# 5. 统计每分钟请求数(看高峰时段)
cat /var/log/nginx/access.log | awk '{print $4}' | cut -d: -f1-3 | uniq -c

# 6. 找出所有 500 错误
grep " 500 " /var/log/nginx/access.log

# 7. 查看错误日志
tail -100 /var/log/nginx/error.log

# 8. 如果发现某个 IP 恶意访问,封掉它
sudo iptables -A INPUT -s 恶意IP -j DROP

实用技巧:

# 组合使用 - 找出今天 10 点到 11 点的 500 错误
grep "01/Dec/2024:10:" /var/log/nginx/access.log | grep " 500 "

# 使用 awk 提取特定字段
# $1=IP, $4=时间, $7=URL, $9=状态码, $10=响应大小
cat access.log | awk '$9==500 {print $1, $7}'

案例三:定时备份数据库

场景:MySQL 数据库需要每天凌晨自动备份。

# 1. 创建备份脚本
vim ~/backup_mysql.sh
#!/bin/bash
# MySQL 备份脚本

# 配置
BACKUP_DIR="/home/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_USER="root"
DB_PASS="your_password"
DB_NAME="your_database"

# 创建备份目录
mkdir -p $BACKUP_DIR

# 执行备份
mysqldump -u$DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/$DB_NAME-$DATE.sql.gz

# 删除 7 天前的备份
find $BACKUP_DIR -type f -mtime +7 -delete

# 记录日志
echo "[$DATE] 备份完成: $DB_NAME-$DATE.sql.gz" >> $BACKUP_DIR/backup.log
# 2. 添加执行权限
chmod +x ~/backup_mysql.sh

# 3. 测试运行
./backup_mysql.sh

# 4. 添加定时任务
crontab -e

# 添加这行:每天凌晨 3 点执行
0 3 * * * /home/user/backup_mysql.sh

改进版 - 带通知的备份脚本:

#!/bin/bash
# 带通知的备份脚本

BACKUP_DIR="/home/backup/mysql"
DATE=$(date +%Y%m%d_%H%M%S)
DB_NAME="your_database"

# 执行备份
if mysqldump -uroot -p'password' $DB_NAME | gzip > $BACKUP_DIR/$DB_NAME-$DATE.sql.gz; then
    echo "备份成功" | mail -s "MySQL 备份成功 - $DATE" admin@example.com
else
    echo "备份失败!" | mail -s "⚠️ MySQL 备份失败 - $DATE" admin@example.com
fi

案例四:批量处理文件

场景:需要把一堆图片批量重命名、压缩、上传。

# 1. 批量重命名(添加日期前缀)
for file in *.jpg; do
    mv "$file" "$(date +%Y%m%d)_$file"
done

# 2. 批量重命名(替换空格为下划线)
for file in *\ *; do
    mv "$file" "${file// /_}"
done

# 3. 批量转换图片格式(需要 ImageMagick)
for file in *.png; do
    convert "$file" "${file%.png}.jpg"
done

# 4. 批量压缩图片
for file in *.jpg; do
    convert "$file" -quality 80 "compressed_$file"
done

# 5. 批量上传到服务器
for file in *.jpg; do
    scp "$file" user@server:/path/to/images/
done

# 更高效的批量上传
rsync -avz --progress *.jpg user@server:/path/to/images/

实用的批处理脚本:

#!/bin/bash
# 批量处理图片:压缩 + 重命名 + 归档

INPUT_DIR="./raw"
OUTPUT_DIR="./processed"
mkdir -p $OUTPUT_DIR

count=1
for file in $INPUT_DIR/*.{jpg,png,jpeg}; do
    [ -e "$file" ] || continue  # 文件不存在则跳过
    
    # 生成新文件名
    ext="${file##*.}"
    newname=$(printf "image_%03d.%s" $count $ext)
    
    # 压缩并保存
    convert "$file" -quality 85 -resize "1920x1080>" "$OUTPUT_DIR/$newname"
    
    echo "处理: $file -> $newname"
    ((count++))
done

# 打包
tar -czvf processed_images_$(date +%Y%m%d).tar.gz $OUTPUT_DIR/
echo "完成!共处理 $((count-1)) 个文件"

案例五:服务器安全加固

场景:新服务器上线前的安全配置。

# 1. 修改 SSH 端口(防止扫描)
sudo vim /etc/ssh/sshd_config
# 修改 Port 22 为其他端口,如 Port 2222

# 2. 禁止 root 直接登录
# 在 sshd_config 中设置
PermitRootLogin no

# 3. 只允许密钥登录
PasswordAuthentication no
PubkeyAuthentication yes

# 4. 重启 SSH
sudo systemctl restart sshd

# 5. 配置防火墙
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 2222/tcp    # SSH 新端口
sudo ufw allow 80/tcp      # HTTP
sudo ufw allow 443/tcp     # HTTPS
sudo ufw enable

# 6. 安装 fail2ban(防暴力破解)
sudo apt install fail2ban -y
sudo systemctl enable fail2ban
sudo systemctl start fail2ban

# 7. 检查可疑登录
last                        # 登录记录
lastb                       # 登录失败记录
cat /var/log/auth.log | grep Failed

安全检查清单:

# 检查监听端口
ss -tlnp

# 检查运行中的服务
systemctl list-units --type=service --state=running

# 检查定时任务
crontab -l
cat /etc/crontab

# 检查用户列表
cat /etc/passwd | grep -v nologin

# 检查 sudo 权限
cat /etc/sudoers

案例六:监控系统资源

场景:写一个简单的监控脚本,资源超限发告警。

#!/bin/bash
# 简单监控脚本 monitor.sh

# 阈值
CPU_THRESHOLD=80
MEM_THRESHOLD=85
DISK_THRESHOLD=90

# 获取资源使用率
CPU_USAGE=$(top -bn1 | grep "Cpu(s)" | awk '{print $2}' | cut -d'%' -f1)
MEM_USAGE=$(free | grep Mem | awk '{printf("%.0f", $3/$2 * 100)}')
DISK_USAGE=$(df / | tail -1 | awk '{print $5}' | tr -d '%')

# 检查并告警
ALERT=""

if (( $(echo "$CPU_USAGE > $CPU_THRESHOLD" | bc -l) )); then
    ALERT+="⚠️ CPU 使用率过高: ${CPU_USAGE}%\n"
fi

if (( MEM_USAGE > MEM_THRESHOLD )); then
    ALERT+="⚠️ 内存使用率过高: ${MEM_USAGE}%\n"
fi

if (( DISK_USAGE > DISK_THRESHOLD )); then
    ALERT+="⚠️ 磁盘使用率过高: ${DISK_USAGE}%\n"
fi

# 发送告警
if [ -n "$ALERT" ]; then
    echo -e "$(date)\n$ALERT" >> /var/log/monitor_alert.log
    # 可以接入企业微信、钉钉等通知
    # curl -X POST -H "Content-Type: application/json" -d '{"text":"'$ALERT'"}' https://webhook.url
fi

添加到 crontab,每 5 分钟检查一次:

*/5 * * * * /home/user/monitor.sh

😱 血泪教训总结

教训一:rm -rf 惨案

🚨 真实案例

有人想删除 /home/user/test 目录,结果多打了个空格:

rm -rf / home/user/test

然后...整个系统就没了 💀

防护措施:

# 1. 给 rm 加保险
alias rm='rm -i'

# 2. 使用 trash-cli 代替 rm
sudo apt install trash-cli
alias rm='trash-put'

# 3. 重要操作前先 echo
echo rm -rf /home/user/test    # 先看看要删什么
rm -rf /home/user/test         # 确认后再执行

# 4. 使用变量时加引号
DIR="/home/user/test"
rm -rf "$DIR"                   # 加引号防止变量为空

# 5. 最安全的删除方式
cd /home/user/
rm -rf ./test                   # 用相对路径

血泪总结:

  • 永远不要在 root 权限下随便 rm -rf
  • 删除前先 ls 看看要删什么
  • 重要数据一定要有备份
  • 考虑用 mv 移到临时目录,而不是直接删

教训二:磁盘空间爆满

😰 真实案例

凌晨收到告警,服务器磁盘满了。 查了半天发现是日志文件占了 50GB...

快速处理:

# 1. 找出罪魁祸首
du -sh /* 2>/dev/null | sort -hr | head -10
du -sh /var/log/* | sort -hr | head -10

# 2. 常见占空间的位置
/var/log/          # 日志
/var/cache/        # 缓存
/tmp/              # 临时文件
~/.cache/          # 用户缓存
Docker 镜像        # docker system df

# 3. 快速清理
sudo apt clean                       # 清理 apt 缓存
sudo journalctl --vacuum-size=100M   # 清理 journald 日志
docker system prune -a               # 清理 Docker(谨慎)

预防措施:

# 1. 设置日志轮转(logrotate)
cat /etc/logrotate.d/nginx
# 确保配置了 rotate 和 maxsize

# 2. 定期清理任务
echo "0 2 * * 0 root /usr/bin/find /tmp -type f -atime +7 -delete" >> /etc/crontab

# 3. 监控磁盘使用
# 在 crontab 添加
*/30 * * * * [ $(df / | tail -1 | awk '{print $5}' | tr -d '%') -gt 85 ] && echo "磁盘告警" | mail -s "Disk Alert" admin@example.com

教训三:SSH 把自己锁在外面

😭 真实案例

改了 SSH 配置,测试没问题就断开了连接。 结果新配置有问题,再也连不上了...

正确的 SSH 配置修改流程:

# 1. 修改配置前先备份
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak

# 2. 保持当前连接,开一个新终端测试
# 千万不要断开当前连接!

# 3. 修改配置
sudo vim /etc/ssh/sshd_config

# 4. 检查配置语法
sudo sshd -t

# 5. 重启 SSH(保持当前连接)
sudo systemctl restart sshd

# 6. 用新终端测试连接
# 能连上再断开旧连接

如果已经被锁在外面:

  1. 通过云服务商的 VNC/Web 控制台连接
  2. 恢复备份配置:cp /etc/ssh/sshd_config.bak /etc/ssh/sshd_config
  3. 重启 SSH 服务

教训四:环境变量搞混

🤔 真实案例

在 .bashrc 里改了 PATH,结果写错了,所有命令都找不到了... 连 vim 都用不了。

紧急恢复:

# PATH 变量坏了?用完整路径
/bin/vim ~/.bashrc
/usr/bin/vim ~/.bashrc

# 或者临时恢复 PATH
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

# 然后修复配置
vim ~/.bashrc
source ~/.bashrc

正确的修改方式:

# 1. 修改前先备份
cp ~/.bashrc ~/.bashrc.bak

# 2. 添加 PATH 用追加方式,不要直接覆盖
export PATH=$PATH:/new/path    # ✅ 追加
export PATH=/new/path          # ❌ 覆盖会丢失原有路径

# 3. 在新终端测试
# 不要在当前终端 source,先开新终端看效果

教训五:字符编码问题

🔤 真实案例

脚本在本地跑得好好的,传到服务器就报错。 原因:Windows 换行符是 \r\n,Linux 是 \n

诊断和修复:

# 1. 检查文件类型
file script.sh
# 如果显示 "with CRLF line terminators" 就是换行符问题

# 2. 查看特殊字符
cat -A script.sh
# ^M 表示 \r

# 3. 转换换行符
dos2unix script.sh
# 或者
sed -i 's/\r$//' script.sh

# 4. Vim 中转换
:set ff=unix
:wq

预防措施:

# Git 配置自动转换
git config --global core.autocrlf input

# 使用 EditorConfig
# .editorconfig 文件
[*]
end_of_line = lf
charset = utf-8

教训六:忘记加 nohup

😅 真实案例

跑了一个要执行 3 小时的脚本,SSH 断开后发现进程也没了...

正确的后台运行方式:

# 1. nohup - 最常用
nohup ./long_running_script.sh &
nohup ./script.sh > output.log 2>&1 &

# 2. screen - 可以重新连接
screen -S mysession
./long_running_script.sh
# Ctrl+A, D 断开
# screen -r mysession 重新连接

# 3. tmux - 更现代的选择
tmux new -s mysession
./long_running_script.sh
# Ctrl+B, D 断开
# tmux attach -t mysession 重新连接

# 4. systemd - 正式服务
# 创建 service 文件
sudo vim /etc/systemd/system/myservice.service

tmux 快速入门:

# 安装
sudo apt install tmux

# 新建会话
tmux new -s work

# 断开但不结束
Ctrl+B, D

# 重新连接
tmux attach -t work

# 列出所有会话
tmux ls

教训七:权限设置不当

🔐 真实案例

为了省事把某个目录设成了 777,结果被人植入了木马...

权限最佳实践:

# 1. 最小权限原则
# 文件:644(rw-r--r--)
# 目录:755(rwxr-xr-x)
# 脚本:755(rwxr-xr-x)
# 敏感配置:600(rw-------)

# 2. Web 目录权限
chown -R www-data:www-data /var/www/html
chmod -R 755 /var/www/html
chmod -R 644 /var/www/html/*.php

# 3. SSH 密钥权限
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_rsa          # 私钥
chmod 644 ~/.ssh/id_rsa.pub      # 公钥
chmod 600 ~/.ssh/authorized_keys

# 4. 永远不要
chmod 777 任何东西  # ❌ 太危险
chmod -R 777 /      # ❌ 系统会崩溃

💡 保命好习惯

操作前必做

# 1. 重要操作前先备份
cp config.conf config.conf.bak.$(date +%Y%m%d)

# 2. 删除前先列出
ls target_dir/      # 看看要删什么
rm -rf target_dir/  # 确认后再删

# 3. 修改前先看内容
cat /etc/xxx.conf
vim /etc/xxx.conf

# 4. 批量操作先测试
echo "测试命令"    # 先 echo 看看
实际命令            # 确认后再执行

写脚本的好习惯

#!/bin/bash
set -e          # 遇到错误立即退出
set -u          # 使用未定义变量报错
set -o pipefail # 管道中的错误也捕获

# 或者一行
set -euo pipefail

操作记录

# 1. 用 script 记录操作
script operation_$(date +%Y%m%d).log
# 执行操作...
exit

# 2. 重要变更写注释
vim /etc/nginx/nginx.conf
# 在修改处添加注释
# Modified by xiaoming on 2024-12-01: 增加缓存配置

定期备份

# 重要配置文件
/etc/nginx/
/etc/ssh/
/etc/mysql/
/etc/crontab

# 应用数据
/var/www/
数据库

# 建议使用版本控制
cd /etc
sudo git init
sudo git add .
sudo git commit -m "Initial config"

📝 本章小结

案例清单

场景关键技术
部署网站Nginx + scp/rsync + 权限设置
日志分析grep + awk + sort + uniq
定时备份Shell 脚本 + crontab
批量处理for 循环 + 变量替换
安全加固SSH + 防火墙 + fail2ban
系统监控top/free/df + 告警脚本

血泪教训

教训预防措施
rm -rf 删错使用 trash-cli、先 echo
磁盘爆满监控 + 日志轮转
SSH 锁外面保持连接测试
环境变量错用追加方式、先备份
换行符问题dos2unix 转换
忘记 nohup使用 tmux/screen
权限太松最小权限原则

保命口诀

🛡️ 运维保命口诀

操作之前先备份,
删除之前先看清。
配置改完别断连,
后台任务用 screen。
权限别给 777,
日志定期要清理。

🎯 长安的下一步建议

学到这里,你已经具备了 Linux 的实战能力!长安建议你:

  1. 多动手实践 - 找个云服务器玩玩
  2. 记录踩坑经历 - 建立自己的知识库
  3. 学习进阶内容 - Docker、K8s、自动化运维
  4. 参与开源项目 - 实战是最好的老师

🔥 长安的最后忠告

不怕犯错,就怕不备份!

每一次翻车都是成长的机会,但前提是你能恢复回来 😄


🎉 恭喜你完成了 Linux 新手村的所有课程!

如果觉得长安的教程对你有帮助,欢迎来编程指南社区交流学习心得,我们一起进步!

—— 编程指南社区 · 长安

最后更新: 2025/12/1 15:56
Prev
🔧 故障排查