I wrote a script for comparing two folders

Hi all, :wave:

I´ve written a script for comparing 2 folders. :blush:

Often enough I like to know whether the contents of two folders (which once have been identical or still are) have changed or not.
For this I wrote the following script:

#!/bin/bash

echo "enter the path of the two folders to be compared"
echo
read -p "input: folder 1   " ordner1
echo
read -p "input: folder 2   " ordner2

find $ordner1 -type f -exec sha256sum {} + > /tmp/sums.sha256
sleep 1.0
find $ordner2 -type f -exec sha256sum {} + > /tmp/2sums.sha256
sleep 1.0
cd /tmp
awk '{print $1}' sums.sha256 | sort > 1test.txt
awk '{print $1}' 2sums.sha256 | sort > 2test.txt
sleep 1.0
diff 1test.txt 2test.txt
echo
sleep 1.0
while true
    do
	read -p "proceed? input:   y, n    " a
	if [ "$a" == "y" ]
            then
		rm /tmp/sums.sha256
		rm /tmp/2sums.sha256
		rm /tmp/1test.txt
		rm /tmp/2test.txt
            else
		exit
	fi
    done
exit

It went through without any difficulties. :wink:

Here´s the protocol of bash -x:

bash -x ./script_Inhalt_von_Ordnern_vgl.sh 

+ echo 'enter the path of the two folders to be compared'
enter the path of the two folders to be compared
+ echo

+ read -p 'input: folder 1   ' ordner1
input: folder 1   /media/rosika/0002-2D2B/aus_dem_Internet/A-Internet-Filme/
+ echo

+ read -p 'input: folder 2   ' ordner2
input: folder 2   /media/rosika/f14a27c2-0b49-4607-94ea-2e56bbf76fe1/vom_alten_32GB_usb-stick/aus_dem_Internet/A-Internet-Filme/
+ find /media/rosika/0002-2D2B/aus_dem_Internet/A-Internet-Filme/ -type f -exec sha256sum '{}' +
+ sleep 1.0
+ find /media/rosika/f14a27c2-0b49-4607-94ea-2e56bbf76fe1/vom_alten_32GB_usb-stick/aus_dem_Internet/A-Internet-Filme/ -type f -exec sha256sum '{}' +
+ sleep 1.0
+ cd /tmp
+ awk '{print $1}' sums.sha256
+ sort
+ awk '{print $1}' 2sums.sha256
+ sort
+ sleep 1.0
+ diff 1test.txt 2test.txt
0a1
> 030b00ac474c0d07231eecd4a6ee498e196c373ff755603ef91108fac93c850b
3d3
< 463cd0022378c3774e88a85686f4c3ca8699a3859df664629ceaba9b2fe26994
+ echo

+ sleep 1.0
+ true
+ read -p 'kann es weiter gehen? Eingabe:   j, n    ' a
kann es weiter gehen? Eingabe:   j, n    j
+ '[' j == j ']'
+ rm /tmp/sums.sha256
+ rm /tmp/2sums.sha256
+ rm /tmp/1test.txt
+ rm /tmp/2test.txt
+ true
+ read -p 'proceed? input:   y, n     ' a
proceed? input:   y, n     n
+ '[' n == j ']'
+ exit
rosika@rosika-Lenovo-H520e ~/D/K/prov [1]> echo $status
1

The last question I first answered affirmatively so that the tmp files would be deleted.
After that the last question was asked again and this time I negated it so that the script would exit.

BTW: the result was that out of the 18 files only one was different.

The protocol didn´t seem to produce any errors.

Still the exit code is 1. :thinking:

Does anyone know why that is :question:

Many thanks and many greetings from Rosika :slightly_smiling_face:

1 Like

Should that be folder 2 on second line?

I think the exit status 1 may be bacause you exited by jumping out of a loop.
Try break instead of exit inside the loop

I use bash -ex

I think files in /tmp disappear on reboot. There may be no need to rm them.

That seems like a useful script. Well done.

1 Like

Hi Neville, :wave:

thanks so much for your reply. :heart:

Of course. You´re perfectly right, Neville. You´re very attentive. :+1:

I wrote my original script in German and translated the respective input prompts for the forum here. It was a simple translation mistake. Sorry.
I corrected it in the meantime.

That´s the solution. Thank you. :heart:
Although I still had to use bash -x. Curiously enough bash -ex didn´t run the script properly…
The part

while true
    do
	read -p "proceed? input:   y, n    " a
	if [ "$a" == "y" ]
            then
		rm /tmp/sums.sha256
		rm /tmp/2sums.sha256
		rm /tmp/1test.txt
		rm /tmp/2test.txt
            else
		break
	fi
    done
exit

was skipped. No idea why that is. :thinking:

But bash -x worked the way it was intended to and the exit code was zero now.

Ah, now I get it: here it says:

-e Exit immediately if a command exits with a non-zero status.

That´s surely the reason why the last part was skipped. :blush: .

Thanks for the praise, Neville.

It´s just a rudimentary script and surely can be refined as to its output messages.
As it is at the moment it works like this:

If there´s no output then the contents of the 2 folders are the same or haven´t changed.
If there´s been change the different hashes of the respective files are printed.

Thanks so much, Neville.

Many greetings from Rosika :slightly_smiling_face:

Oh yes,
the diff will return nonzero status

I have a couple of directories I can try it with

1 Like

Thanks, Neville, for the confirmation. :heart:

Cheers from Rosika :slightly_smiling_face:

I assume that’s for debugging? Never tried this - I still use (in my scripts if I want to troubleshoot) :

set -vx

In my shell scripts if I want to debug, that’s something I inherited from ksh, and works in bash too… When done, I usually just comment it out…

Might look at “-x” and “-ex” in future when running a script and I want to see things like variables getting populated and what they’re populated with - thanks for the pointer :smiley:

2 Likes

Thanks, Dan, for your comment. :heart:

Yes, that´s right.

To me, set -vx is new, I have to admit.
I found a discussion about the two variants for debugging scripts here:
linux - Bash -x or set -x - Stack Overflow .

I´ll look into it.
Thanks for the hint.

Many greetings from Rosika :slightly_smiling_face:

I find set -x confusing, because in a csh script, set is used to set the value of a variable.

Hi Neville. :wave:

I see. In this case then, I think bash -x or bash -ex should be the better solution.

I still have to look into Dan´s variant.
Wouldn´t know how to correctly use it in the first place. :blush:

Cheers from Rosika :slightly_smiling_face:

1 Like

I looked at Daniel’s link.
Apparently one can use set -x to log just part of a script. That could be useful if you just want fo log one part of a long script.

Not many people use csh today. Part of my BSD heritage.

1 Like

Yes, that´s surely a huge advantage, especially if a script has a certain length.
But set -x would be a line within the script, right? :thinking:
If so, one would have to get rid of it in the final version of the script when debugging is no longer needed…

Cheers fro Rosika :slightly_smiling_face:

Hi Rosika,

Thats is right. You have to edit it in, then remove it later. Just like putting a print statement in a program to debug it.

Will you script work if one of the 2 directories has extra files?

Regards
Neville

Hi Neville, :wave:

thanks for the confirmation. :+1:

I guess so.

Hang on, I´ll give it a try.

@nevj :

Yes, Neville. Extra files are taken care of as well. :blush:

Taking up the example from my post #1 I added two extra text-files in the first folder (only here):
BTW: this time I ran my original script, so the output is in German. Sorry. But you´ll get the gist of it.

Here´s the output:

./script_Inhalt_von_Ordnern_vgl.sh
Welche zwei Ordner sollen miteinander verglichen werden?

Eingabe: Ordner 1   /media/rosika/0002-2D2B/aus_dem_Internet/A-Internet-Filme/

Eingabe: Ordner 2   /media/rosika/f14a27c2-0b49-4607-94ea-2e56bbf76fe1/vom_alten_32GB_usb-stick/aus_dem_Internet/A-Internet-Filme/
0a1
> 030b00ac474c0d07231eecd4a6ee498e196c373ff755603ef91108fac93c850b
3d3
< 463cd0022378c3774e88a85686f4c3ca8699a3859df664629ceaba9b2fe26994
13d12
< 9d8128b9c773307df9d30af7be74e69b05eae2b76ceea3265a937d9a22f317b3
18d16  # this is new
< e703a44e5c3576206d1febf8ba1b55d56349317932eedea4c4beaad9f11269fc  # this is new

kann es weiter gehen? Eingabe:   j, n    j
kann es weiter gehen? Eingabe:   j, n    n

So the output is 4 lines this time.

2 lines accounting for one file different in each directory. That was already the case before.
2 lines new, as I added 2 text files only in directory 1 but not in directory 2.

Many greeting from Rosika :slightly_smiling_face:

1 Like

Very Nice, i love what you done in the script

2 Likes

Thanks @privatesecure for your praise. :heart:

As I already said, it´s only rudimentary at the moment and certainly could be refined.

As it is just now it more or less only informs you whether there are any differences in the two folders compared and you can deduce how many files are affected.
That´s it for the main part.

But the good thing is: subfolders are also accounted for.

My main goal was to have a quick-and-dirty script available as I´m in the middle of transferring all the files (in folders and subfolders) from one USB-stick to another and want to make sure I have the exact same contents available… :blush: .

Thanks again and many greetings from Rosika. :slightly_smiling_face:

Hi @Rosika,

I was impressed with your script writing skills.
When I want to see if everything was copied, I do a right click on the folder and click on properties. It gives the count of the number of items and size of the folder. Then I do the same for the other folder.

If I want to see what has changed or update a backup of one folder to anther, I use a free open source program (GUI) called Free File Sync. It show everything that is different between the two folders in an easy to read format.

2 Likes

Hi Howard, :wave:

thanks for the additional info. :heart:

I see. I checked with thunar and indeed it works the same way with me.
Great. :+1:

I just l took a look at the ubuntuusers-wiki site and they have a really great article on free file sync (in German though) but they say:

FreeFileSync is not included in the official package sources

Such a shame. :neutral_face:

One of the other possibilities is compiling from source code.

Thanks, Howard, for mentioning free file sync. It seems like a really useful programme.

Many greetings from Rosika :slightly_smiling_face:

P.S.:

Thanks so much, Howard, but I´m just dabbling.

It is apparently possible to use diff -qr folder1 folder2
I have not tried it.
See the diff man page

1 Like

Thanks, Neville, for the suggestion. :heart:

I never had cause to use anything different than diff and diff -s.
So I looked it up:

-r, –recursive recursively compare any subdirectories found.

I´ve learnt something new again. :wink:

Many greetings from Rosika :slightly_smiling_face: