【Linux系统】Linux 命令行查看当前目录的总大小/总磁盘空间

'# 【Linux系统】Linux 命令行查看当前目录的总大小/总磁盘空间

一、背景与问题

在Linux系统中,监控磁盘空间使用情况是系统管理的重要任务。开发人员和运维人员常常需要快速获取目录或文件的磁盘占用情况,例如:

  • 查看某个项目目录的总大小
  • 确定某个服务的配置文件夹是否异常膨胀
  • 分析日志文件占用空间的分布

传统方式中,du(disk usage)命令是标准工具,但其底层实现机制和性能特征值得深入探讨。本文将从底层文件系统操作、命令行工具实现、性能优化等多个维度展开分析。

二、基本原理

Linux文件系统通过 inode 记录文件元信息,每个文件(包括目录)都有对应的 inode,其中包含文件大小、权限、时间戳等信息。要统计目录总大小,需要:

  1. 遍历目录树中的所有文件
  2. 获取每个文件的磁盘占用(块大小)
  3. 汇总统计结果

关键点在于:

  • 文件系统的块大小(通常为4KB)
  • 隐藏文件(如.svn)对统计结果的影响
  • 符号链接的处理方式
  • 硬链接与软链接的区别

三、环境准备

确保系统支持以下功能:

# 检查文件系统类型
df -Th
# 检查磁盘空间
df -h
# 安装必要的工具(如未预装)
sudo apt install coreutils  # Debian/Ubuntu
sudo yum install coreutils  # CentOS/RHEL

四、核心实现

1. 使用 du 命令(推荐方案)

# 查看当前目录的总大小(以GB显示)
du -sh
# 查看当前目录下所有子目录的大小(按大小排序)
du -sh * | sort -hr

关键代码解释:

  • -s 选项表示统计每个参数的总大小
  • h 选项将数值转换为可读格式(如K/M/G)
  • --apparent-size 选项用于统计文件的显示大小(不包含隐藏文件)

性能优化技巧:

  • 使用 --max-depth=1 限制遍历深度
  • 通过 --block-size=1 改变块大小计算方式
  • 使用 --no-dereference 忽略符号链接

2. 使用 find + wc 组合

# 统计当前目录下所有文件的总大小(以字节为单位)
find . -type f -printf "%s\n" | awk '{sum += $1} END {print sum}'
# 以MB为单位显示
find . -type f -printf "%s\n" | awk '{sum += $1} END {print sum/1024/1024}'

原理分析:

  • -type f 仅匹配普通文件
  • -printf "%s\n" 输出文件大小(字节数)
  • awk 脚本进行数值计算

性能问题:

  • 对于包含大量文件的目录(如 /var/log),可能需要数秒才能完成
  • 可通过 --max-depth 限制遍历深度

3. 自定义 Shell 脚本实现

#!/bin/bash

# 获取文件系统块大小
BLOCK_SIZE=$(stat -f -c "%s" .)

# 遍历目录树
find . -type f -printf "%s\n" | awk -v block="$BLOCK_SIZE" '
{
    sum += $1
}
END {
    printf "Total size: %.2f MB\n", sum / 1024 / 1024
    printf "Block size: %d bytes\n", block
    printf "Total blocks: %.2f\n", sum / block
}'

关键点:

  • stat 命令获取文件系统块大小
  • printf 格式化输出
  • awk 进行数值计算

五、完整案例

案例:监控项目目录磁盘使用

场景描述:
某微服务项目部署在生产服务器,需定期检查 /opt/myapp 目录的磁盘占用情况

实现方案:

#!/bin/bash

# 定义监控参数
DIR="/opt/myapp"
THRESHOLD="10G"
LOG="/var/log/disk_usage.log"

# 获取当前目录大小
CURRENT_SIZE=$(du -s "$DIR" | awk '{print $1}')

# 比较大小
if [ "$CURRENT_SIZE" -gt "$(echo "$THRESHOLD" | sed 's/G/*1024/;s/M/*1024/;s/K/*1/')" ]; then
    echo "$(date) - Warning: $DIR is over $THRESHOLD" | tee -a "$LOG"
    du -sh "$DIR" | tee -a "$LOG"
else
    echo "$(date) - $DIR is within normal limits" | tee -a "$LOG"
fi

运行结果示例:

Wed May 10 14:30:00 UTC 2023 - /opt/myapp is over 10G
12G     /opt/myapp

注意事项:

  • 需要 sudo 权限才能访问某些系统目录
  • 每次运行会追加记录到日志文件
  • 可结合 crontab 实现定时监控

六、源码解析(du 命令实现)

以 GNU coreutils 中的 du 命令为例,其核心逻辑如下(简化版):

#include <stdio.h>
#include <sys/stat.h>
#include <dirent.h>

void traverse_dir(const char *path) {
    DIR *dir = opendir(path);
    if (!dir) return;

    struct dirent *entry;
    while ((entry = readdir(dir))) {
        char full_path[PATH_MAX];
        snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);

        struct stat st;
        if (stat(full_path, &st) == 0) {
            // 处理文件/目录
            if (S_ISDIR(st.st_mode)) {
                traverse_dir(full_path);
            } else {
                // 计算文件大小
                size_t size = st.st_blocks * st.st_blksize;
                // 更新总大小统计
                total_size += size;
            }
        }
    }
    closedir(dir);
}

关键点:

  • 使用 opendir/readdir 遍历目录
  • 通过 stat 获取文件属性
  • 使用 st_blocks 和 st_blksize 计算磁盘占用
  • 对于目录,递归调用 traverse_dir

七、进阶使用

1. 多线程处理

# 使用GNU parallel加速文件统计
find . -type f -printf "%s\n" | parallel -j 8 --block 1M awk '{sum += $1} END {print sum}'

2. 结合 inotify 实时监控

# 使用 inotifywait 实时监控目录变化
inotifywait -m -r -e modify,create,delete /opt/myapp | while read path action file; do
    echo "Directory change detected in $path"
    du -sh /opt/myapp
done

3. 与监控系统集成

# 输出可被 Prometheus 抓取的指标
echo "# HELP disk_usage Total disk usage of the directory"
echo "# UNIT bytes"
echo "$(( $(du -s /opt/myapp | awk '{print $1}') * 1024 ))"

八、性能与工程实践

1. 性能优化策略

场景优化方法效果
大型目录使用 --max-depth 限制遍历深度减少I/O操作
高频监控缓存最近统计结果减少重复计算
系统目录使用 --no-dereference 忽略符号链接避免误统计
网络文件系统限制并发线程数避免网络拥塞

2. 异常处理

# 增加错误处理的脚本
if ! du -s "$DIR" > /dev/null 2>&1; then
    echo "Error: Failed to get disk usage for $DIR"
    exit 1
fi

3. 安全考虑

  • 检查执行权限:find 需要对目标目录的读取权限
  • 避免符号链接漏洞:使用 --no-dereference 参数
  • 谨慎处理用户输入:过滤特殊字符
  • 在生产环境中使用 sudo 时要严格控制权限

九、常见问题与踩坑

1. 常见错误示例

错误代码:

find . -type f -printf "%s\n" | wc -l

问题分析:

  • wc -l 统计的是文件数量而非大小
  • 会统计隐藏文件(如 .git)

改进方案:

find . -type f -printf "%s\n" | awk '{sum += $1} END {print sum}'

2. 性能瓶颈

问题现象:

  • 对 /proc 目录使用 du 时卡顿

原因分析:

  • /proc 是虚拟文件系统,遍历会触发大量 syscalls

解决方法:

  • 使用 du --apparent-size 避免实际磁盘空间计算
  • 限制遍历深度:du --max-depth=1

3. 磁盘空间不一致问题

现象:

  • du 显示的总大小与 df 不一致

原因分析:

  • du 统计的是文件占用的块数
  • df 显示的是文件系统剩余空间
  • 隐藏文件/符号链接可能影响统计

解决方法:

  • 使用 du --block-size=1 查看精确块数
  • 检查是否有未关闭的文件描述符

十、最佳实践

1. 推荐方案选择

场景推荐方案原因
快速概览du -sh简洁高效
精确统计find + awk可自定义逻辑
监控系统自定义脚本可集成监控系统
高并发并行处理提高处理效率

2. 禁用使用场景

  • 不要直接使用 du 监控系统关键目录(如 /)
  • 不要用 find 统计大量小文件(会消耗大量内存)
  • 不要对只读文件系统使用 du(会报错)

3. 安全最佳实践

  • 对敏感目录使用 --no-dereference 避免符号链接漏洞
  • 在脚本中加入权限检查
  • 限制脚本的运行权限(如通过 sudo 的 NOPASSWD 配置)

十一、总结

Linux 系统中查看目录磁盘占用的核心工具 du,其底层实现涉及文件系统的 inode 管理和目录遍历机制。通过理解其工作原理,我们可以更有效地使用该工具解决实际问题。

在实际开发中:

  • 推荐使用 du -sh 快速获取目录大小
  • 对于复杂需求,可结合 find 和 awk 实现定制化统计
  • 在监控系统中,建议采用自定义脚本进行定期检查
  • 避免在关键系统目录使用未经验证的脚本

同时要注意:

  • 大型目录的统计可能需要数秒时间
  • 隐藏文件和符号链接可能影响统计结果
  • 系统文件的读取权限需要特别注意

通过合理使用这些工具,可以显著提升系统管理效率,避免因磁盘空间不足导致的生产事故。

最后修改于:2026年10月01日 22:41

评论已关闭

推荐阅读

AIGC实战——Transformer模型
2024年12月01日
Socket TCP 和 UDP 编程基础(Python)
2024年11月30日
python , tcp , udp
如何使用 ChatGPT 进行学术润色?你需要这些指令
2024年12月01日
AI
最新 Python 调用 OpenAi 详细教程实现问答、图像合成、图像理解、语音合成、语音识别(详细教程)
2024年11月24日
ChatGPT 和 DALL·E 2 配合生成故事绘本
2024年12月01日
omegaconf,一个超强的 Python 库!
2024年11月24日
【视觉AIGC识别】误差特征、人脸伪造检测、其他类型假图检测
2024年12月01日
[超级详细]如何在深度学习训练模型过程中使用 GPU 加速
2024年11月29日
Python 物理引擎pymunk最完整教程
2024年11月27日
MediaPipe 人体姿态与手指关键点检测教程
2024年11月27日
深入了解 Taipy:Python 打造 Web 应用的全面教程
2024年11月26日
基于Transformer的时间序列预测模型
2024年11月25日
Python在金融大数据分析中的AI应用(股价分析、量化交易)实战
2024年11月25日
AIGC Gradio系列学习教程之Components
2024年12月01日
Python3 `asyncio` — 异步 I/O,事件循环和并发工具
2024年11月30日
llama-factory SFT系列教程:大模型在自定义数据集 LoRA 训练与部署
2024年12月01日
Python 多线程和多进程用法
2024年11月24日
Python socket详解,全网最全教程
2024年11月27日
python之plot()和subplot()画图
2024年11月26日
理解 DALL·E 2、Stable Diffusion 和 Midjourney 工作原理
2024年12月01日