MD5 sum of a directory

From Noah.org
Jump to: navigation, search


This returns an MD5 sum of a given directory path. It attempts to compensate for potential differences in the order of files on different filesystems. It accounts only for filenames and the contents of files. Other metadata should not effect the resulting hash.

Symlinks are not followed except when the given directory is a symlink. Symlinks do count in the filename hashing, so name changes and deletions of symlinks would be detected by the hash.

#!/bin/sh

######################################################################
#
# dirmd5
#
# SYNOPSIS
#
#     dirmd5 [PATH]
#
# DESCRIPTION
#
#     This returns the md5sum of an entire directory.
#     The only argument is the path to process.
#     If no path is given then the current directory is used.
#     It attempts to detect filename changes and
#     to compensate for sort differences in different filesystems.
#
# EXAMPLES
#
#     $ dirmd5 /home/noah/project
#     70b8fd2ac11844e9507e30a980ecdc00
#
# EXIT STATUS
#
#     This exits with status 0 on success or non-zero on error.
#
# AUTHOR
#
#     Noah Spurrier <noah@noah.org>
#
# LICENSE
#
#     This license is OSI and FSF approved as GPL-compatible.
#     This license identical to the ISC License and is registered with and
#     approved by the Open Source Initiative. For more information vist:
#         http://opensource.org/licenses/isc-license.txt
#
#     Copyright (c) 2013, Noah Spurrier <noah@noah.org>
#
#     Permission to use, copy, modify, and/or distribute this software for any
#     purpose with or without fee is hereby granted, provided that the above
#     copyright notice and this permission notice appear in all copies.
#
#     THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
#     WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
#     MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
#     ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
#     WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
#     ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
#     OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
# VERSION
#
#     Version 1
#
######################################################################

if [ "$1" ]; then
        ROOT_PATH="$1"
else
        ROOT_PATH="$(pwd)"
fi
ROOT_PATH="$(cd ${ROOT_PATH} && pwd)"
# Follow the first sym-link, if any.
if readlink ${ROOT_PATH}; then
        ROOT_PATH=$(readlink ${ROOT_PATH})
fi
(
find "${ROOT_PATH}" -type f | while read fn; do md5sum "$fn"; done
find "${ROOT_PATH}" -type d | sed 's/\/$//'
) | LC_ALL=C sort | md5sum | sed 's/^\([[:xdigit:]]\+\).*/\1/'