macOS 所有物理磁盘的底层唯一标识符由 Serial Number 和 Device Identifier 共同构成:前者由制造商固件写入,后者如 disk0 或 IODeviceTree 路径反映硬件拓扑,二者结合确保稳定不可伪造;diskutil info 提取序列号最通用,ioreg 补充获取被屏蔽序列号的设备路径,system_profiler 可按接口类型关联协议与标识符。
要查 macos 所有物理磁盘的底层唯一标识符,核心是获取每个磁盘的 **serial number(序列号)** 和 **device identifier(设备路径)**,二者共同构成稳定、不可伪造的物理身份。仅靠卷名或挂载点不行,因为它们可变;而序列号由制造商写入固件,设备路径(如 iodevicetree:/pci0@0/peg0@1c/pci0@0)反映真实硬件拓扑,两者结合才真正“唯一”。
用 diskutil info 提取各磁盘序列号
这是最直接、兼容性最好的方式,适用于内置 SSD、USB、Thunderbolt 等所有类型物理磁盘:
- 先列出全部物理磁盘(不含分区):
diskutil list | grep -E '^/dev/disk[0-9]+$' - 对每个磁盘(如
disk0)执行:diskutil info disk0 | awk '/Serial Number|Device Identifier/ {print $1, $2, $3, $4}' - 结果示例:
Serial Number: WXS123456789
Device Identifier: disk0
用 ioreg 获取更底层的设备路径与序列号
当 diskutil 未返回序列号(常见于某些 USB 桥接芯片硬盘),ioreg 可穿透驱动层读取 IOService 层原始属性,尤其适合外置硬盘真伪验证:
- 运行命令一次性提取所有块存储设备的序列号和设备树路径:
ioreg -c IOBlockStorageDriver -r -d 1 | awk -F' = ' '/"Serial Number"|IODeviceTree/ {gsub(/"/, "", $2); print $1 ": " $2}' | grep -E "(Serial Number|IODeviceTree)" - 输出类似:
Serial Number: ABC987654321
IODeviceTree: /PCI0@0/PEG0@1C/PCI0@0/NVMe@0,1 - 注意:该路径能区分同一型号多块盘,即使序列号被隐藏或桥接芯片屏蔽,路径仍唯一
按接口类型筛选并关联协议与标识符
若需同时知道“哪块盘走什么协议+它的唯一 ID”,可组合使用 system_profiler 和 diskutil:
- 查 NVMe 盘:
system_profiler SPNVMeDataType | awk '/BSD Name|Serial Number|Link Width/ {gsub(/^[ \t]+|[ \t]+$/, ""); print}' - 查 USB/Thunderbolt 外置盘:
system_profiler SPUSBDataType | awk '/Product ID|Serial Number|BSD Name/ {gsub(/^[ \t]+|[ \t]+$/, ""); print}' - 输出中 “BSD Name”(如
disk2)即对应diskutil info中的设备标识,“Serial Number”即物理唯一码
一键汇总所有物理磁盘的唯一标识(推荐脚本)
把上述逻辑自动化,以下脚本会列出每块物理磁盘的挂载点(如有)、设备名、序列号、协议和设备路径:
for d in $(diskutil list | grep '^/dev/disk[0-9]$' | awk '{print $1}'); do<br> sn=$(diskutil info "$d" 2>/dev/null | grep "Serial Number" | awk -F': ' '{print $2}' | tr -d ' ')<br> proto=$(diskutil info "$d" 2>/dev/null | grep "Protocol" | awk -F': ' '{print $2}' | tr -d ' ')<br> path=$(ioreg -c IOBlockStorageDriver 2>/dev/null | grep -A5 "$d" | grep "IODeviceTree" | awk -F'= ' '{print $2}' | tr -d '" ')<br> mp=$(df -P | grep "^$d" | awk '{print $6}' | head -1)<br> echo "$mp → $d (SN: $sn, Proto: $proto, Path: ${path:-N/A})"<br>done | sort


















