作为一名Linux系统管理员,我每天都要和磁盘空间打交道。记得刚入行时,服务器突然报磁盘空间不足,我手忙脚乱地到处删除文件,结果误删了重要日志。后来师父教我用du命令,才真正掌握了磁盘空间管理的正确姿势。今天我就把自己十年积累的du命令使用心得完整分享给大家。
du(disk usage)命令是Linux系统自带的磁盘空间分析工具,它通过遍历文件系统的inode节点来统计磁盘使用情况。与df命令显示文件系统整体使用情况不同,du专注于单个文件和目录的精确统计。
这个命令的核心原理其实很简单:
注意:du统计的是磁盘块的实际占用,而不是文件大小。比如一个1字节的文件可能占用4K的磁盘空间,这是因为文件系统的最小分配单元是4K。
最基本的用法就是直接运行du命令:
bash复制$ du
12 ./logs
8 ./cache
1024 ./data
1044 .
这个输出表示:
使用--max-depth控制递归深度:
bash复制$ du --max-depth=1 /var
1024 /var/log
512 /var/cache
2048 /var/lib
3584 /var
这个命令只显示/var下第一级子目录的大小。
加上-h参数让输出更友好:
bash复制$ du -h /home/user
4.0K /home/user/.ssh
12M /home/user/Documents
1.2G /home/user/Videos
1.3G /home/user
使用--exclude过滤不需要统计的目录:
bash复制$ du -h --exclude='*.log' /var
这个命令会跳过所有.log文件。
-s参数可以只显示总计大小:
bash复制$ du -sh /home
1.3G /home
结合find命令可以统计文件数量:
bash复制$ find /var -type f | wc -l
$ du -h /var
对于特别大的目录,可以:
bash复制$ du -h --max-depth=2 --nocache /bigdir > du.log &
使用-x参数防止跨文件系统扫描:
bash复制$ du -xh /
bash复制#!/bin/bash
THRESHOLD=90
CURRENT=$(df / | grep / | awk '{print $5}' | sed 's/%//g')
if [ "$CURRENT" -gt "$THRESHOLD" ]; then
echo "WARNING: 根分区使用率 ${CURRENT}%" | mail -s "磁盘警报" admin@example.com
du -h --max-depth=1 / | sort -hr | head -10 >> /var/log/disk_usage.log
fi
bash复制#!/bin/bash
find / -type f -size +100M -exec du -h {} + | sort -rh | head -20
bash复制#!/bin/bash
LOG_DIR=/var/log
RETENTION=30
find $LOG_DIR -type f -name "*.log" -mtime +$RETENTION -exec rm -f {} \;
du -sh $LOG_DIR | mail -s "日志清理完成" admin@example.com
可能原因:
解决方法:
bash复制$ lsof +L1 # 查看被删除但未释放的文件
$ quota -v # 检查磁盘配额
$ fsck /dev/sda1 # 修复文件系统
使用sudo提升权限:
bash复制$ sudo du -h /root
或者先获取目录列表再统计:
bash复制$ find /var -type d -exec sudo du -s {} + 2>/dev/null
通过实际测试比较不同参数的效率:
| 命令 | 耗时(秒) | 内存占用(MB) |
|---|---|---|
| du -h / | 12.3 | 45 |
| du -h --max-depth=3 / | 5.7 | 32 |
| du -h --exclude='*.log' / | 10.1 | 38 |
| du -h -x / | 8.9 | 41 |
从测试可以看出,合理使用参数可以显著提升性能。
根据多年经验,我总结出以下黄金法则:
去年我们一个生产环境突然报磁盘空间不足。使用du命令分析后发现是Nginx日志没有轮转,单个日志文件已经达到20GB。通过以下步骤解决:
bash复制$ du -h /var/log/nginx/* | sort -rh | head -5
bash复制$ > /var/log/nginx/access.log
bash复制$ cat /etc/logrotate.d/nginx
/var/log/nginx/*.log {
daily
rotate 7
compress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
/etc/init.d/nginx reload >/dev/null
endscript
}
bash复制# 统计图片文件大小
$ find . -type f -name "*.jpg" -o -name "*.png" | xargs du -ch | grep total
bash复制$ du -h --exclude='/mnt/*' /
bash复制# 统计最近7天修改的文件
$ find . -mtime -7 -type f -exec du -ch {} + | grep total
当du命令结果异常时,可以按照以下步骤排查:
对于超大型文件系统(如超过100万个文件),常规du命令可能很慢。这时可以采用:
bash复制$ find / -type d -print0 | xargs -0 -P4 -n1 du -s
bash复制$ ncdu / # 需要安装ncdu
bash复制$ for d in /var /home /opt; do du -sh $d; done
bash复制# 查找大于100MB的mp4文件
$ find . -type f -name "*.mp4" -size +100M -exec du -h {} +
bash复制# 计算目录平均文件大小
$ du -s /home/* | awk '{sum+=$1; count++} END {print "平均大小:" sum/count/1024"MB"}'
bash复制$ du -h --max-depth=1 / | sort -rh | head -10 | bar
在Docker容器中,du命令同样适用:
bash复制# 查看容器内磁盘使用
$ docker exec -it mycontainer du -h /data
# 统计容器日志大小
$ docker ps -q | xargs docker inspect --format='{{.LogPath}}' | xargs du -h
在某电商平台的运维实践中,我们建立了完整的磁盘监控体系:
核心脚本片段:
bash复制#!/bin/bash
# 记录历史数据
TIMESTAMP=$(date +%s)
du -s /data/{logs,db,cache} | awk -v ts=$TIMESTAMP '{print ts,$1}' >> /var/log/disk_usage.log
# 生成趋势图
rrdtool graph /var/www/disk.png --start -7d \
DEF:logs=/var/log/disk_usage.log:1:AVERAGE \
LINE2:logs#FF0000:"Logs"
经过多次优化,我们总结出du命令的最佳实践:
想要深入掌握磁盘管理,推荐学习:
随着技术发展,du命令也在进化:
在多年的运维生涯中,du命令是我最常用的工具之一。它看似简单,实则蕴含巨大能量。掌握好这个命令,不仅能快速解决磁盘空间问题,更能深入理解Linux文件系统的工作原理。记住,一个好的系统管理员不是等到磁盘满了才去处理,而是通过定期监控和分析,把问题消灭在萌芽状态。