// Linux · 2025-03-11

Linux的“人性化选项”:-h(或 --human-readable)

1. 引言:当计算机的“语言”遇上人类的直觉

在 Linux 的世界里,计算机习惯于使用精确但晦涩的单位:字节、纳秒、inode 编号。而对于人类来说,1.5G 远比 1610612736 直观,Jan 15 10:30 远比 1736929800(Unix 时间戳)亲切。

-h(或 --human-readable)选项正是为了架起这座桥梁而诞生的。它不是某一个命令的专利,而是 Linux 核心工具集(GNU Coreutils)中广泛采纳的设计惯例。

核心价值:当命令的输出包含数字(尤其是文件大小、时间、数量)时,启用该选项可以将原始数据格式化为适合人类阅读和快速理解的表示方式。

2. 核心功能:把大数字变成日常语言

2.1 单位转换逻辑

-h 的核心算法是将原始字节数自动换算为最合适的单位,并保留 1-2 位小数:

原始字节 换算过程 人类可读输出
450 < 1024 450
1536 1536 ÷ 1024 = 1.5 1.5K
2,097,152 2,097,152 ÷ 1024² = 2 2.0M
1,234,567,890 1.15 × 1024³ = 1.15 1.15G

2.2 常用场景速查

命令 默认输出 启用 -h 后 作用对象
ls -l 4096 4.0K 文件/目录大小
df 1048576 1.0G 磁盘分区容量
du 2097152 2.0M 目录总占用
free -m 以 MiB 为单位 -h 自动选单位 内存使用量
dd (status=progress) 精确字节数 1.2 GB 传输速率/总量

3. 核心命令的 -h 实践

3.1 ls -lh:友好的文件列表

这是最常用的组合,用于查看文件详细属性。

# 普通长格式
$ ls -l /usr/bin/docker
-rwxr-xr-x 1 root root 71988968 Oct 10  2024 /usr/bin/docker

# 带上 -h 的人类可读版本
$ ls -lh /usr/bin/docker
-rwxr-xr-x 1 root root 69M Oct 10  2024 /usr/bin/docker

控制小数精度:GNU ls 支持 --block-size 强制单位,但不支持直接控制小数位数。若需精确控制,可结合 numfmt:

ls -l --block-size=MiB   # 强制以 MiB 为单位
ls -l | awk '{print $5}' | numfmt --to=iec

3.2 df -h:查看磁盘分区容量

df 报告文件系统磁盘空间使用情况。

# 默认(单位:1K 块)
$ df /
Filesystem     1K-blocks     Used Available Use% Mounted on
/dev/sda2       5119912  1574876   3280128  33% /

# 人类可读
$ df -h /
Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       4.9G  1.5G  3.2G  33% /

进阶:df -h --total 在末尾显示总计行;df -i -h 显示 inode 使用情况的人类可读格式。

3.3 du -sh:查看目录总大小

du 用于估算文件和目录的磁盘使用空间。

# 分别列出子目录大小(原始字节)
$ du /var/log
4864    /var/log/apt
12288   /var/log

# 人类可读 - 汇总
$ du -sh /var/log
12M     /var/log

# 人类可读 - 带明细(--si 使用 1000 进制)
$ du -h /var/log
4.8K    /var/log/apt
12M     /var/log

3.4 free -h:内存与交换分区

# 默认显示(以 KiB 为单位)
$ free
              total        used        free      shared  buff/cache   available
Mem:       16275288     5426216     2113780      438372     8735292     9780460
Swap:       2097148           0     2097148

# 人类可读
$ free -h
              total        used        free      shared  buff/cache   available
Mem:           15Gi       5.2Gi       2.0Gi       428Mi       8.3Gi       9.3Gi
Swap:         2.0Gi          0B       2.0Gi

单位差异说明:free -h 默认使用二进制单位(MiB/GiB),而 free --si 使用十进制单位(MB/GB)。在 Linux 中,“G” 通常代表 Gibibyte (GiB, ×1024³),但某些工具(如 dd)遵循国际单位制,其中 “G” 代表 Gigabyte (×1000³)。

3.5 dd 与 -h 替代

dd 原生命令不支持 -h,但从 coreutils 8.24+ 开始支持 status=progress,可显示人类可读进度:

dd if=/dev/zero of=/dev/null bs=1M count=1000 status=progress
# 输出:419430400 bytes (419 MB, 400 MiB) copied, 1 s, 419 MB/s

若要独立转换数字,可使用 numfmt:

echo "1610612736" | numfmt --to=iec   # 输出:1.5G

4. 变体与进阶

4.1 -H:更符合国际单位制的“硬”选项

部分命令(如 du、df)同时提供 -h 和 -H,两者区别在于进位标准:

选项 进制 单位 1K =
-h 二进制 KiB, MiB, GiB 1024 字节
-H 十进制 KB, MB, GB 1000 字节
# 二进制(传统):1M = 1024K
du -h /path

# 十进制(SI 国际单位):1M = 1000K
du -H /path

4.2 numfmt:通用的数字格式转换器

GNU Coreutils 8.21+ 提供的 numfmt 可将任意数字转换为人类可读格式,非常适合脚本处理:

# 单次转换
numfmt --to=iec 1024000       # 1000K

# 从标准输入读取
df --output=used | tail -n +2 | numfmt --to=iec

# 处理日志中的字节数
cat access.log | awk '{print $10}' | numfmt --to=iec --field=1

numfmt 常用参数:

参数 作用
--to=si 转换为 SI 单位(1000 进制)
--to=iec 转换为 IEC 单位(1024 进制)
--to=iec-i 转换为带 ‘i’ 后缀(如 1.5Ki)
--to=none 去除单位,仅数字
--padding=N 输出右对齐,宽度为 N
--field=N 处理输入中的第 N 个字段

4.3 -h 在非 GNU 系统中的差异

macOS/BSD 系统:大多使用 BSD 版工具集(源自 FreeBSD),行为与 GNU 略有不同:

  • ls -lh:功能类似
  • df -h:默认使用 1024 进制,可通过 -H 使用 1000 进制

BusyBox(嵌入式系统):通常提供精简版 -h 支持,但单位精度可能较低。

跨平台兼容建议:尽可能用 numfmt 作统一处理,避免直接依赖 -h 的输出格式。

5. 可视化效果与实际场景

5.1 生产环境日志分析

# 按请求大小排序,找出占用带宽最多的前10个请求
cat access.log | awk '{print $10, $7}' | sort -rn | head | numfmt --to=iec --field=1

5.2 磁盘清理脚本

# 找出最大的 5 个文件或目录,结果带单位
du -sh /* 2>/dev/null | sort -rh | head -5
# sort -r 逆序, -h 识别 'K','M','G' 后缀

5.3 监控磁盘使用率

watch -n 5 'df -h | grep -E "/($|data)"'

6. 扩展阅读与 FAQ

Q1:为什么 ls -l 默认不用 -h?

因为脚本解析 ls 输出时,4096 比 4.0K 更可靠——人类可读格式(带单位、小数、国际化字符)会破坏脚本的文本解析逻辑。因此 -h 默认关闭,供交互式使用。

Q2:ls -lh 能否控制小数位数?

不能。GNU ls 的小数位数由内部算法决定,通常为 1 位或 2 位。若要精确控制,请使用 numfmt 进行后处理。

Q3:如何判断一个命令是否支持 -h?

绝大多数 GNU Coreutils 命令(ls、df、du)都支持。非 coreutils 命令(如 docker、systemctl)往往也仿照此惯例。最可靠的方式是查看 man command 或 command --help 输出的 “Human readable” 字样。

Q4:Windows 的 -h 存在吗?

Windows PowerShell 提供了 Format-HumanReadable;Git Bash 中的 ls 支持 -h。

7. 总结:-h 的设计哲学

-h 选项的本质,是在工具设计层面承认一个事实:机器可读性与人类可读性是不同的需求。

  • 默认输出优先保证“可解析”——规范、简单、无歧义
  • -h 作为可选模式,服务于“可理解”——直观、友好、有上下文
# 脚本解析(不用 -h)
used_percent=$(df / | awk 'NR==2 {print $5}' | tr -d '%')

# 人类检查(用 -h)
df -h

这个设计模式(默认机器友好 + 可选人类友好)在 Linux 生态中被广泛复制——--color(高亮输出)、--timestamp(时间戳)等选项都遵循同样的逻辑。理解 -h,也就理解了 Linux 工具设计的底层逻辑之一:尊重人类认知局限,但不牺牲机器效率。

-h 的完整速查表:

命令 典型用法 作用
ls ls -lh 文件大小由字节转为 K/M/G
df df -h 磁盘分区容量
du du -sh 目录总占用汇总
free free -h 内存与交换区
numfmt numfmt --to=iec 通用数字转换(脚本)

原文 https://blog.csdn.net/2301_79518550/article/details/146187316