Running diff and have it stop on a difference

bash, diff, linux

Solution

You can do the loop over files with 'find' and break when they differ. eg for dirs foo, bar:

for file in $(find foo -type f); do if [[ $(diff -q $file ${file/#foo/bar}) ]]; then   echo differs: $file; break; else echo same: $file; fi; done

NB this will not detect if 'bar' has directories that do not exist in 'foo'.

Edited to add: I just realised I overlooked the really obvious solution:

diff -rq foo bar | head -n1

Problem

I have a script running that is checking multiples directories and comparing them to expanded tarballs of the same directories elsewhere. I am using `diff -r -q` and what I would like is that when `diff` finds any difference in the recursive run it will stop running instead of going through more directories in the same run. All help appreciated! Thank you @bazzargh I did try it like you suggested or like this. ``` for file in $(find $dir1 -type f); do if [[ $(diff -q $file ${file/#$dir1/$dir2}) ]]; then echo differs: $file > /tmp/$runid.tmp 2>&1; break; else echo same: $file > /dev/null; fi; done ``` But this only works with files that exist in both directories. If one file is missing I won't get information about that. Also the directories I am working with have over 300.000 files so it seems to be a bit of overhead to do a `find` for each file and then `diff`. I would like something like this to work, with and `elif` statement that checks if `$runid.tmp` contains data and breaks if it does. I added `2>` after the first `if` statement so `stderr` is sent to the `$runid.tmp` file. ``` for file in $(find $dir1 -type f); do if [[ $(diff -q $file ${file/#$dir1/$dir2}) ]] 2> /tmp/$runid.tmp; then echo differs: $file > /tmp/$runid.tmp 2>&1; break; elif [[ -s /tmp/$runid.tmp ]]; then echo differs: $file >> /tmp/$runid.tmp 2>&1; break; else echo same: $file > /dev/null; fi; done ``` Would this work?

Original source