mtree(8) is an excellent tool for this:
$ mtree -cp path/on/hostA -K sha256 | ssh hostB mtree -p path/on/hostB
will report differences between the heirarchy in
hostA:path/on/hostA and the heirarchy in
hostB:path/on/hostB in terms of type, size, timestamp, permissions, and content. Additionally, missing entries (not found on
hostB) or extraneous entries (found only on
hostB) are reported.
If the heirarcies are identical,
mtree will issue no output and return an exit code of 0:
$ mtree -cp path/on/hostA -K sha256 | ssh hostB mtree -p path/on/hostB && echo match
mtree will return a non-zero exit code, and itemize the entries that differ:
# create some differences on hostB:
$ ssh hostB 'rmdir path/on/hostB/d'
$ ssh hostB 'mkdir path/on/hostB/e'
$ ssh hostB 'date > path/on/hostB/b/B'
$ ssh hostB 'touch path/on/hostB/b/BB'
$ ssh hostB 'chmod 644 path/on/hostB/c/C'
# and then compare:
$ mtree -cp path/on/hostA -K sha256 | ssh hostB mtree -p path/on/hostB || echo fail
.: modification time (Tue May 18 13:27:20 2021, Tue May 18 13:45:06 2021)
b/BB: modification time (Tue May 18 13:27:28 2021, Tue May 18 13:50:01 2021)
b/B: modification time (Tue May 18 13:27:03 2021, Tue May 18 13:46:04 2021)
sha256 (0x4f7986b5a925296c575043e73e76b59b6eb84da37c50f2e86baaafc75e2fcdca, 0x46f3f4e748cfef2a4cd679d6c9723cb44eb0526b760854fcef33bb97ca27fae2)
c/C: permissions (0600, 0644)
Line by line,
mtree tells you that:
- the path root directories themselves (
.) have different timestamps
- there is an extra entry
hostB that does not appear on
- the modification time of entry
b/BB differs between the two hosts (but the content does not)
- the modification time AND the content (
SHA256 hash) of entry
b/B differ between the two hosts
- the permissions of entry
c/C differ between the two hosts
hostB is missing the entry