资讯动态

一文详解md5sum:在Ubuntu和macOS上构建跨平台文件完整性校验工具

发布时间:2026/10/27 1:30:08 来源:尧图企业网站定制
在数字时代文件传输和存储过程中可能会遭遇各种意外情况网络传输错误、存储介质损坏、恶意篡改等。这些风险可能导致关键文件损坏或内容被修改进而引发严重后果。文件完整性校验技术应运而生成为确保数据安全的必要手段。MD5Message-Digest Algorithm 5是一种广泛使用的哈希算法能够为任意长度的数据生成唯一的128位哈希值。虽然MD5在密码学领域已不再安全但在文件完整性校验方面它仍然是一个简单有效的工具。本文将介绍 LinuxUbuntu下的md5sum命令以及 macOS 上对应的md5命令并给出一个在 Ubuntu 和 macOS 上都可直接运行的自动化文件完整性校验脚本。一、md5sum 与 md5 工具md5sum是 GNU coreutils 中的一个经典命令行工具其核心功能是计算并验证文件的 MD5 哈希值。MD5 哈希如同一份文件的“数字指纹”任何微小的内容改动都会导致其哈希值发生剧烈变化。通过比较文件当前生成的MD5值与之前记录的原始值md5sum能够高效、准确地判断文件在传输、存储或备份过程中是否保持了完整性即是否未被意外损坏或恶意篡改。macOS 同样属于 Unix 类系统但并没有自带md5sum而是提供了 BSD 版本的md5命令。两者针对同一个文件计算出的 MD5 值完全相同差异主要在于命令参数和输出格式md5sum file输出哈希值 文件名并支持用-c直接校验md5 file默认输出MD5 (file) 哈希值需要加-r才能得到与 md5sum 一致的哈希值 文件名格式并且不支持-c校验模式。两个平台的常用命令对比如下操作Ubuntumd5summacOSmd5计算单个文件的哈希md5sum filemd5 -r file仅输出哈希值md5sum file | awk {print $1}md5 -q file批量生成find ... -exec md5sum {} \;find ... -exec md5 -r {} \;批量校验md5sum -c checksums.md5逐行比对见下文或使用gmd5sum -c checksums.md5如果希望在 macOS 上直接使用md5sum的完整功能可以安装 GNU coreutilsbrew install coreutils。安装后会提供带g前缀的gmd5sum其用法与md5sum完全一致。1. 生成单个文件的MD5校验值若您希望在终端中直接查看某个文件的MD5哈希值可以使用以下命令它将输出一个128位的哈希值与对应的文件名# Ubuntu生成文件的MD5值并显示在终端md5sum filename.txt在 macOS 上对应的写法为# macOS-r 参数输出 哈希值 文件名 格式md5-rfilename.txt# 如果只需要哈希值本身md5-qfilename.txt如果您需要将生成的MD5校验值保存下来以供后续使用可以将输出重定向至一个文件这样会创建一个便于日后校验的MD5记录文件# Ubuntu将MD5值保存到文件md5sum filename.txtchecksum.md5# macOS将MD5值保存到文件md5-rfilename.txtchecksum.md52. 校验文件完整性当您拥有一个已存储MD5值的校验文件时可以使用以下命令批量校验对应文件的完整性系统会自动比对当前文件的MD5值与记录是否一致# Ubuntu使用保存的MD5文件校验md5sum-cchecksum.md5macOS 的md5命令没有-c校验模式需要自行读取校验文件并逐行比对。下面是一个最简实现# macOS逐行读取校验文件并比对whileIFSread-rline;do[-z$line]continueexpected${line%%*}file${line#* }file${file#}# 兼容 md5sum 输出中的两个空格if[-f$file][$(md5-q$file)$expected];thenecho$file: OKelseecho$file: FAILEDfidonechecksum.md5当然也可以先执行brew install coreutils然后直接使用gmd5sum -c checksum.md5获得与 Ubuntu 完全一致的校验体验。3. 批量处理文件若要为某个目录下的所有文件生成MD5校验值可以结合find命令实现批量生成结果将统一保存到一个汇总文件中# Ubuntu生成目录下所有文件的MD5值find/home/bjxia/demo-typef-execmd5sum{}\;all_checksums.md5同样也可以基于上述生成的汇总文件对目录中的所有文件进行一次完整的批量校验确保大量文件的完整性状态一目了然# Ubuntu批量校验md5sum-call_checksums.md5在 macOS 上只需把md5sum换成md5 -r# macOS批量生成输出格式与 md5sum 一致find~/Downloads/mask-typef-execmd5-r{}\;all_checksums.md5# macOS批量校验使用上一节的循环或 gmd5sum -cwhileIFSread-rline;doexpected${line%%*}file${line#* };file${file#}[$(md5-q$file)$expected]echo$file: OK||echo$file: FAILEDdoneall_checksums.md54. 批量处理时排除指定目录在实际项目中我们经常需要排除一些临时或自动生成的目录例如node_modules或build文件夹这时可以在find命令中加入排除参数使生成的MD5记录更加简洁和准确# 使用 -not -path 排除目录GNU find 写法find/home/bjxia/demo-typef-not-path*/node_modules/*-not-path*/build/*-execmd5sum{}\;checksums.md5需要注意的是-not、-path这类写法虽然也能被部分 BSD/macOS 版本的find识别但兼容性并不稳定。更稳妥、也更高效的做法是使用-prune直接跳过整个目录这种写法在 GNU find 和 BSD find 中均可正常工作# Ubuntu排除 node_modules、build 目录find$BASE_DIR\(-namenode_modules-o-namebuild\)-prune-o\-typef-execmd5sum{}\;checksums.md5# macOS排除 node_modules、build 目录find$BASE_DIR\(-namenode_modules-o-namebuild\)-prune-o\-typef-execmd5-r{}\;checksums.md5-prune会直接跳过匹配的目录不再递归遍历其中的内容因此比“遍历后再用-path过滤”更快。后文的自动化脚本正是采用这种跨平台写法并借助 Bash 数组组织find参数避免使用eval即使路径中包含空格或特殊字符也能安全处理。二、跨平台自动化脚本通过编写脚本我们可以将校验流程自动化提高工作效率。下面这份自动化校验脚本在 Ubuntu 和 macOS 上均可直接运行它会自动检测系统可用的 MD5 工具并处理两个平台在命令参数、输出格式和校验方式上的差异。此外脚本还支持排除指定目录、通过命令行参数或环境变量配置路径并自动避免把校验文件自身计算进去。#!/usr/bin/env bash# check_integrity.sh - 文件 MD5 生成与校验Linux / macOS 通用## 用法:# 添加执行权限# chmod x md5sum.sh# 输入文件默认当前目录输出文件默认 ~/checksums# ./check_integrity.sh# 指定源目录# ./check_integrity.sh ~/Downloads/mask# 指定源目录和输出目录# ./check_integrity.sh ~/Downloads/mask ~/Downloads/mask# 要计算MD5的文件夹默认当前目录BASE_DIR${1:-${BASE_DIR:-$PWD}}# MD5输出文件夹默认 ~/checksumsMD5_DIR${2:-${MD5_DIR:-$HOME/checksums}}# 要排除的文件夹用空格分隔多个文件夹名EXCLUDE_DIRScmake-build-debug cmake-build-release .ideaif[!-d$BASE_DIR];thenecho错误: 源目录不存在:$BASE_DIRexit1fi# 转成绝对路径保证校验文件里记录的是绝对路径BASE_DIR$(cd$BASE_DIRpwd)mkdir-p$MD5_DIRMD5_DIR$(cd$MD5_DIRpwd)# MD5校验文件的完整路径MD5_FILE$MD5_DIR/md5_checksums.txt# 检测可用的 MD5 工具Linux 用 md5summacOS 用 md5detect_md5_tool(){ifcommand-vmd5sum/dev/null21;thenMD5_BINmd5sumMD5_STYLEgnuelifcommand-vgmd5sum/dev/null21;thenMD5_BINgmd5sumMD5_STYLEgnuelifcommand-vmd5/dev/null21;thenMD5_BINmd5MD5_STYLEbsdelseecho错误: 未找到 md5sum 或 md5 命令exit1fi}# 构建排除目录的 find 表达式-prune 写法 BSD/GNU find 都支持build_find_expr(){FIND_EXPR()localdirprune()fordirin$EXCLUDE_DIRS;do[${#prune[]}-gt0]prune(-o)prune(-name$dir)doneif[${#prune[]}-gt0];thenFIND_EXPR(\(${prune[]}\)-prune-o)fiFIND_EXPR(-type f)# 排除校验文件自身避免输出目录与源目录相同时把自己也计算进去FIND_EXPR(!-path$MD5_FILE)}# 函数生成MD5generate_md5(){echo正在生成MD5校验和...echo源目录:$BASE_DIRecho排除目录:$EXCLUDE_DIRS# 清空旧文件$MD5_FILE# BSD md5 需要 -r 才能输出 hash 文件名 格式if[$MD5_STYLEbsd];thenfind$BASE_DIR${FIND_EXPR[]}-exec$MD5_BIN-r{}\;$MD5_FILEelsefind$BASE_DIR${FIND_EXPR[]}-exec$MD5_BIN{}\;$MD5_FILEfiCOUNT$(grep-c.$MD5_FILE)echo已生成$COUNT个文件的MD5校验和echo保存到:$MD5_FILE}# BSD md5 没有 -c 校验模式这里逐行读取校验文件自行比对verify_md5_bsd(){localline expectedfileactualfailed0checked0whileIFSread-rline||[-n$line];do[-z$line]continue# 兼容 hash fileBSD md5 -r和 hash fileGNU md5sum两种格式expected${line%%*}file${line#* }while[${file#}!$file];dofile${file#}done# GNU md5sum 二进制模式会在文件名前加 *[${file#\*}!$file]file${file#\*}checked$((checked1))if[!-f$file];thenprintf%s: FAILED文件不存在\n$filefailed$((failed1))elseactual$($MD5_BIN -q $file)if[$actual$expected];thenprintf%s: OK\n$fileelseprintf%s: FAILED\n$filefailed$((failed1))fifidone$MD5_FILEif[$failed-gt0];thenprintfmd5: 警告: %s 个文件校验失败共 %s 个\n$failed$checked2return1fireturn0}# 函数校验MD5verify_md5(){echo正在校验文件完整性...if[!-f$MD5_FILE];thenecho错误: MD5文件不存在请先生成MD5:$MD5_FILEreturn1filocalrc0if[$MD5_STYLEgnu];then$MD5_BIN-c$MD5_FILE21||rc$?elseverify_md5_bsd||rc$?fiif[$rc-eq0];thenechoecho✓ 所有文件完整性校验通过return0elseechoecho⚠ 文件完整性校验失败return1fi}detect_md5_tool build_find_expr# 主菜单echo文件完整性管理工具echoecho源目录:$BASE_DIRecho输出目录:$MD5_DIRecho1. 生成MD5校验和echo2. 校验文件完整性echo3. 重新生成并校验printf请选择操作 (1-3): read-rchoicecase$choicein1)generate_md5;;2)verify_md5;;3)generate_md5 verify_md5;;*)echo无效选择exit1;;esac2.1 脚本关键实现自动检测 MD5 工具优先使用md5sumLinux 或安装了 coreutils 的环境其次尝试gmd5sum最后回退到 macOS 自带的md5并用MD5_STYLE区分 GNU 与 BSD 两套处理逻辑。生成命令适配BSD 的md5需要-r参数才能输出与md5sum一致的哈希值 文件名格式脚本据平台自动添加。校验方式适配GNU 环境直接调用md5sum -cmacOS 环境则逐行读取校验文件用md5 -q计算后比对并兼容两种输出格式的空格数量、*标记以及文件丢失的情况。跨平台排除目录用-prune表达式替代-not -path同时用 Bash 数组拼接参数而不是eval路径中包含空格时也不会出错。路径处理源目录和输出目录支持“命令行参数 环境变量 默认值”的优先级并统一转换为绝对路径因此切换工作目录后仍能正确校验。避免校验文件自校验当输出目录与源目录相同例如./md5sum.sh ~/Downloads/mask ~/Downloads/mask时脚本会通过! -path $MD5_FILE把校验文件自身排除在外否则每次重新生成都会改变自身内容导致校验永远失败。统计文件数量使用grep -c而不是wc -l因为 macOS 的wc在读取标准输入时会输出前导空格。2.2 使用方法# 添加执行权限chmodx md5sum.sh# 默认校验当前目录结果保存到 ~/checksums./check_integrity.sh# 指定源目录./check_integrity.sh ~/Downloads/mask# 指定源目录和输出目录两者可以相同./check_integrity.sh ~/Downloads/mask ~/Downloads/mask运行后按提示选择 1生成、2校验或 3重新生成并校验即可。批量生成MD5校验和批量校验MD5校验和

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑