最可靠的方法是用 sudo blockdev --getss /dev/sda 查逻辑扇区大小、sudo blockdev --getpbsz /dev/sda 查物理扇区大小,二者均直读内核ioctl,不依赖fdisk估算或sysfs缓存;若--getpbsz失败,则fallback到cat /sys/block/sda/queue/physical_block_size。

直接看 fdisk -l 输出第三行的 “Sector size (logical/physical)” 最快最准,不用换算、不依赖脚本、不需猜测。
fdisk -l 的 Sector size 行在哪
执行 sudo fdisk -l /dev/sda(把 /dev/sda 换成你的设备),输出开头几行就会有:
Disk /dev/sda: 931.51 GiB, 1000204886016 bytes, 1953525168 sectors Units: sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 4096 bytes I/O size (minimum/optimal): 4096 bytes / 4096 bytes
关键就是第三行:Sector size (logical/physical): 512 bytes / 4096 bytes。左边是逻辑扇区大小(OS 看到的单位),右边是物理扇区大小(磁盘真实写入粒度)。
常见错误现象:
- 没加
sudo:部分未挂载或权限受限的设备会隐藏该行,或只显示模糊信息 - 设备刚插入未识别:比如 NVMe 盘热插拔后内核尚未完成探测,
fdisk -l可能压根不输出这一行 - 误读 “Units” 行:它只说明 “1 sector = 512 bytes”,但这是逻辑单位,不能代表物理对齐基准
blockdev --getss 和 --getpbsz 怎么用
当需要脚本化判断、或 fdisk -l 不可靠时,用 blockdev 直接读取底层值更稳妥:
-
sudo blockdev --getss /dev/sda→ 返回逻辑扇区字节数(如512或4096) -
sudo blockdev --getpbsz /dev/sda→ 返回物理扇区字节数(如4096)
两者相等(如都是 4096)表示真·4K 原生盘;不等(如 512/4096)是 Advanced Format 盘,分区起始必须按物理扇区对齐。
容易踩的坑:
- 对分区设备运行失败:如
blockdev --getpbsz /dev/sda1会报Invalid argument,必须作用于整块磁盘节点(/dev/sda) - USB-SATA 桥接器恒定返回
512:哪怕后端是 SMR 或 NVMe,此时需结合hdparm -I交叉验证 -
--getpbsz失败时 fallback 到cat /sys/block/sda/queue/physical_block_size,这个 sysfs 值比fdisk估算更可信
为什么不能信 lsblk 或 df
lsblk 和 df 完全不涉及扇区概念:
-
lsblk只展示设备树、挂载点、文件系统类型和大小(以字节或 GiB 为单位),不暴露任何扇区级元数据 -
df工作在文件系统层,看到的是已分配的块(block),不是底层 LBA 扇区(sector) - 误用它们查扇区大小,会导致分区对齐错误:例如看到
/dev/sdb总容量是 20G,就用fdisk创建一个 20G 分区,结果mkfs报 “device too small” —— 很可能因未对齐 4K 物理扇区,实际可用空间少了几个 MiB
parted -l 的 Aligned: yes/no 有什么用
sudo parted -l 不显示具体扇区号,但它会在每个分区行末尾标注 Aligned: yes 或 Aligned: no,这个判断基于物理扇区边界(如 4096 字节)计算,比单纯看 Start=2048 是否为整数倍更可靠。
典型场景:
- 某 NVMe 盘物理扇区是
4096字节,逻辑扇区是512,分区Start=2048→ 字节偏移 =2048 × 512 = 1048576,除以4096得256(整除)→Aligned: yes - 若
Start=2049,结果带小数 →Aligned: no -
parted -l内部用的就是blockdev --getpbsz获取的值,所以它比fdisk的估算字段更值得信赖
真正要写底层工具(如 dd 脚本或自动分区对齐逻辑),必须用 blockdev --getpbsz 或 /sys/block/*/queue/physical_block_size,而不是靠 fdisk -l 里那行看起来“方便”的输出——它本质是猜出来的,不是硬件寄存器直读。


















