TL;DR
cd /path/to/working/directory
sha256sum <(find . -type f -exec sha256sum {} \; | sort)
Intro
A more complete answer to the one above, which fixes the problem with find "finding" files in different orders on different systems.
Piping output to file, compare with diff
Firstly, you probably want to pipe the output to a file for comparison with diff. For this you would use
find . -type f -exec sha256sum {} \; > file1.lst
Then on your other system
find . -type f -exec sha256sum {} \; > file2.lst
rsync file2.lst user@host:/home/user/file2.lst
ssh user@host
diff file1.lst file2.lst # might not match due to order
Fixing order of files found with find by piping to sort
Here I am assuming you are doing something similar to what I required this for - copying files from one system to another over a network and verifying the integrity of those files.
What I found was that the order in which find finds files can vary between two systems, even when the OS is "Debian" in both cases.
Therefore, one needs to sort the output in the text files.
sort file1.lst > file1sorted.lst
sort file2.lst > file2sorted.lst
diff file1.lst file2.lst # bad
diff file1sorted.lst file2sorted.lst # ok
You can do the find and sort all in one line, while redirecting the output to a file.
find . -type f -exec sha256sum {} \; | sort > file1.lst
Other sha/md5 sums
You might want to have an increased level of shasumming. To use the 512 bit version simply do;
find . -type f -exec sha512sum {} \; | sort > file1.lst
Alternatively, 256 bit might be overkill for what you are doing, so do
find . -type f -exec md5sum {} \; | sort > file1.lst
A complete 1 line command to compare 2 directories with 1 shasum output
Now, if you have many files and do not want to save the output to a file, you could simply shasum the output. To do this, use
sha256sum <(find . -type -f -exec sha256sum {} \; | sort)
The pipe to sort is required to ensure the output is sorted before computing the final sha256sum. Without this, if find finds files in a different order, despite the shasums for each file being correct, the overall shasum will depend on the order.
Problem relating to diff output and paths used
You may have some path which looks like
/A/B/C/*
where * are the subdirectories and files you are interested in shasumming. If A/B/C are 1 or more directories containing only 1 subfolder you might end up accidentally running your shasum command in the wrong directory, resulting in the following
sort1.txt
sha256sum1 ./A/B/C/file1
sort2.txt
sha256sum2 ./B/C/file1
Even if sha256sum = sha256sum2 diff will say the files are different. (Because they are due to the different base directory in the path.)
Here is a short python3 code to check the sums line by line, which solves this problem.
#!/usr/bin/env python3
file1_name = "sort1.txt"
file2_name = "sort2.txt"
file1 = open(file1_name, 'r')
file2 = open(file2_name, 'r')
file1_lines = file1.readlines();
file2_lines = file2.readlines();
if(len(file1_lines) == len(file2_lines)):
print("line numbers ok")
for i in range(len(file1_lines)):
line1 = file1_lines[i]
line2 = file2_lines[i]
line1_split = line1.split(' ')
line2_split = line2.split(' ')
shasum1 = line1_split[0]
shasum2 = line2_split[0]
if(shasum1 != shasum2):
print("shasum error: ", line1)
else:
print("Error: file ", file1_name, " number of lines != ", file2_name, " number of lines")
print("done")
I initially wanted to write a shell script to do this, but I got bored trying to figure out how to do it, so went back to python.
This makes me think that actually writing a python code to do the entire thing would have been easier, except for the find command.
findis a good way to find files in subdirectories, and with the-execoption it is possible to run commands with parameters{}. Each file found byfindwill be replacing the spaceholder{}, so in your casesha256sumwill work on each of the files one after another. – sudodus Nov 09 '18 at 08:53*) in the output is the only difference. Maybe (I am guessing here) long ago there was some difference (that some characters in binary files could create problems like truncation of the process). – sudodus Nov 09 '18 at 14:34findfinds files, which appears to be implementation dependent. On two different debian machines I have here, the order is changed. I am not sure why this is the case. – user3728501 Sep 04 '20 at 10:26findfail to find all files in the current directory and its subdirectories; 2. Does the activation ofsha256sumfail to run; 3. Or is something else failing for you? - If I understand correctly, this should work in all current versions of Ubuntu, but I have not tested it in Debian. – sudodus Sep 04 '20 at 10:40\r\nfor line endings and text mode will convert that to\n. For any Linux, binary and text modes should be the same. – Mark Ransom Aug 23 '22 at 20:17.gitignoreetc.,sha256sum $(find * .* -type f | sort) | sha256sumcould help orsha256sum $(find . -type f | sort | cut -c 3-)this if you want to capture all files & remove./in-front of the file name in case of nested directories.. – harshavmb Nov 30 '23 at 10:19find . -type f -print0 | xargs -0 sha256sum. To remove the./, use file's%Pformat specifier:find . -type f -printf '%P\0' | xargs -0 sha256sum --The--in the later example is necessary as files could start with a dash, turning them into asha256sumoption if they come as the first file on the command line. – Thomas Guyot-Sionnest Feb 15 '24 at 07:58