tar:打包压缩
先把工具认清
四个参数
# 打包并压缩
$ tar czf backup.tar.gz /etc/nginx
# 解包
$ tar xzf backup.tar.gz
# 只看内容不解开 ← 恢复前一定先看
$ tar tzf backup.tar.gz | head
# 解到指定目录
$ tar xzf backup.tar.gz -C /tmp/restore/
字母的含义
- c / x / t
- create 创建 / extract 解开 / list 列表。三选一。
- z
- 用 gzip 压缩。文件名带
.gz就要加它。(j是 bz2,J是 xz,压得更小但更慢) - f
- 指定文件名,后面紧跟文件名。
f必须放在最后一个字母位置。 - v
- 显示处理过程。脚本里别加——会刷屏、拖慢速度。
记法
打包 czf,解包 xzf,看看 tzf。三个记住就够用。
备份脚本
/opt/backup.sh
#!/bin/bash
#=========================================
# backup.sh —— 备份配置,保留 7 天
#=========================================
set -u
SRC_LIST="/etc/nginx /etc/ssh" # 要备份什么
DST="/backup" # 备份放哪
KEEP_DAYS=7 # 保留几天
DATE=$(date +%F)
LOG="/var/log/backup.log"
mkdir -p "$DST" # Day 02:-p 已存在也不报错
for src in $SRC_LIST; do
name=$(basename "$src") # /etc/nginx → nginx
file="$DST/${name}-${DATE}.tar.gz"
if tar czf "$file" "$src" 2>/dev/null; then
size=$(du -h "$file" | cut -f1)
echo "$(date '+%F %T') 备份成功 $file ($size)" >> "$LOG"
else
echo "$(date '+%F %T') [失败] 备份 $src 出错" >> "$LOG"
fi
done
#—— 清理过期备份(Day 05 的 -mtime +N)——
deleted=$(find "$DST" -name "*.tar.gz" -mtime +$KEEP_DAYS -print -delete | wc -l)
echo "$(date '+%F %T') 清理了 ${deleted} 个过期备份" >> "$LOG"
几个设计考虑
- 文件名带日期
nginx-2026-09-07.tar.gz——一眼知道是哪天的,也不会互相覆盖。- 用 if 判断 tar 是否成功
- 备份最怕"以为备了其实没备"。判断返回值并记日志,才知道到底成没成。
- -print -delete 组合
find删除时同时打印删了哪些,日志里能追溯。- 保留天数做成变量
- 磁盘紧张时改一个数字就行。
备份最重要的一件事
比备份本身还重要
没验证过的备份,等于没有备份
很多事故是这样的:出事了,去拿备份,发现备份是空的、或者根本解不开——脚本报错了但没人看日志。
所以要定期做恢复演练。这句话在面试里很有分量。
恢复演练怎么做
# 1. 先看包里有什么(别直接解到原位置!)
$ tar tzf /backup/nginx-2026-09-07.tar.gz | head
# 2. 解到临时目录验证
$ mkdir -p /tmp/restore
$ tar xzf /backup/nginx-2026-09-07.tar.gz -C /tmp/restore/
$ ls -l /tmp/restore/etc/nginx/
# 3. 和当前配置对比,确认内容是对的
$ diff /tmp/restore/etc/nginx/nginx.conf /etc/nginx/nginx.conf
注意 tar 默认是相对路径解压——包里存的是 etc/nginx/...(去掉了开头的 /),所以解到 /tmp/restore 会变成 /tmp/restore/etc/nginx/。这个特性避免了误覆盖系统文件。
日志切割:别自己写
今天的核心观念
日志会一直涨。你可能想写个脚本定期删——但系统自带的 logrotate 比你写的强得多,而且它已经在你机器上跑着了。
看看它已经在管什么
$ cat /etc/logrotate.conf # 全局默认
$ ls /etc/logrotate.d/ # 每个服务一个配置
nginx sssd chrony dnf
$ cat /etc/logrotate.d/nginx
给自己的日志加一份配置
$ sudo vi /etc/logrotate.d/mycheck
/var/log/check.log {
daily # 每天切一次
rotate 7 # 保留 7 份
compress # 旧的压缩成 .gz
delaycompress # 延迟一轮再压(避免正在写的被压)
missingok # 文件不存在也不报错
notifempty # 空文件不切
create 644 root root # 切完新建一个,指定权限属主
}
几个关键指令
- daily / weekly / size 100M
- 按时间或大小触发切割。生产上常用
size——按大小更可控。 - rotate 7
- 保留 7 份历史,再老的自动删。
- create 644 root root
- 切割后立刻创建新的空文件并设好权限。不加这个,服务可能因为找不到文件而写不进日志。
- copytruncate
- 另一种模式:先复制再清空原文件。适合那些不支持"重新打开日志文件"的程序——Day 21 那个「rm 了但空间没释放」的问题,用它可以避免。
测试配置(别直接等它自己跑)
$ sudo logrotate -d /etc/logrotate.d/mycheck
↑ -d = debug,只演练不执行,看它打算做什么
$ sudo logrotate -f /etc/logrotate.d/mycheck
↑ -f = force,强制立刻执行一次,用于验证
-d 先演练,这是好习惯
和 nginx -t、mount -a 一个道理——这三十天里反复出现的模式:动手前先验证。
今天的面试点
「日志文件太大怎么处理?」
别答"写脚本定期删"——那说明你不知道有现成方案。
「用系统自带的 logrotate:可以按大小或时间切割、自动压缩、保留 N 份自动删。配置放 /etc/logrotate.d/,改完用 logrotate -d 先演练一遍。」
加一句更好:「如果程序不支持重新打开日志文件,就用 copytruncate 模式,避免出现「文件删了但空间没释放」的情况。」
「你们的备份策略是什么?」
「配置文件每天 tar 打包,文件名带日期,保留 7 天,用 find -mtime +7 -delete 自动清理,挂在 crontab 凌晨跑。」
然后一定加这句:「另外我会定期做恢复演练——把备份解到临时目录验证能不能正常打开。没验证过的备份等于没有备份。」
这句话的分量比前面所有命令加起来都重。
今天的练习
敲完再走 · 约 18 分钟
- 练 tar 三件套:
tar czf /tmp/t.tar.gz /etc/ssh→tar tzf看内容 →tar xzf ... -C /tmp/r/解开 - 手敲
/opt/backup.sh,chmod +x后跑一次,看/backup/和/var/log/backup.log - 验证备份可用:解到
/tmp/restore,用diff和当前配置对比 - 测试清理逻辑:
sudo touch -d "10 days ago" /backup/old-test.tar.gz造一个 10 天前的文件,重跑脚本看它被删掉 - 写
/etc/logrotate.d/mycheck,用logrotate -d演练 sudo logrotate -f强制执行一次,看/var/log/下多出check.log.1- 把备份脚本挂到 crontab:
0 2 * * * /opt/backup.sh
明天是最后一天
Day 30 不敲命令——把这三十天串成四段能说出口的话,练怎么在面试里讲。
学会了但说不出来,等于没学。