Hi,

I am Rajesh. I am totally new to shell scripting. I have to prepare a shell script which comapres two directory tree structures ( directory contents comparision is not necessary).

for example, suppose I had installed a software system long back and now I want to upgrade that software but I dont want to disturb the tree stucture. So I had to check the directory tree structure of Updated software with the directory tree strucure of previous version software.
here is the code I am preparing for this problem..but I am not able to achieve my goal. So please, If anyone can review the code and point out where I am going wrong, I would be thankful to them.

the code is :

---------------------------------------------------------------------
#!/bin/bash
#
# compare: compare directory trees recursively and report the differences.
# Author: Rajesh thota

function gettype () {
  if [ -d $1 ]; then
    echo "directory"
  else
    echo "notdirectory"
  fi
}

function exists () {
  if [ -e $1 -o -L $1 ]; then
    return 0;
  else
    echo "rajesh $1 does not exist."
    return 1;
  fi
}

function comparedirectory () {
  local result=0
  local v1=0
  local v2=0
  for i in `(ls -A $1 && ls -A $2) | sort | uniq`; do
#       v1=$(gettype $1/$i)
#       v2=$(gettype $2/$i)
#       echo "$v1"
#       echo "$v2"
#       if [ ($v1 = "directory") && ($v2 = "directory") ]; then
            compare $1/$i $2/$i || result=1
#       fi
  done
  return $result
}

# compare directories
function compare () {
 (exists $1 && exists $2) || return 1;
  local type1=$(gettype $1)
  local type2=$(gettype $2)

  echo "$type1"
  echo "$type2"

  if [ $type1 = $type2 ]; then
           comparedirectory $1 $2
  else
    echo "type mismatch: $type1 ($1) and $type2 ($2)."
    false
  fi
  return
}

if [ 2 -ne $# ]; then
cat << EOU
Usage: $0 dir1 dir2
Compare directory trees:
  directories are checked for identical tree stuctures

  exit 10
fi
---------------------------------------------------------------------

Thanking you a lot

Regards
Rajesh

Dani AI

Generated

started in the right direction and ’s note about using find is on the right track. The key is to compare pathnames (the tree shape) rather than basenames or file contents, and to do that reliably: avoid parsing ls output, always quote expansions, and produce canonical, sorted lists of relative paths before running diff/comm.

Common problems in the posted script: unquoted variables (break on spaces/globs), using ls for machine parsing, incorrect test syntax ([ ... ] combined with &&/|| inside), and listing with ls ... && ls ... which suppresses the second list if the first fails. Those lead to missed entries and false mismatches.

A simple, robust pattern is to generate sorted lists of relative directory paths from inside each tree and compare them. For example:

(cd /path/to/treeA && find . -type d -mindepth 1 -print | sed 's|^\./||' | LC_ALL=C sort > /tmp/treeA.dirs)
(cd /path/to/treeB && find . -type d -mindepth 1 -print | sed 's|^\./||' | LC_ALL=C sort > /tmp/treeB.dirs)

# show entries only in A, only in B, or both (comm -3 shows both-side differences)
comm -3 /tmp/treeA.dirs /tmp/treeB.dirs

To catch file-vs-directory collisions, produce a list that includes type markers (directory, file, symlink) and compare those lists. Symlinks and mounts deserve explicit policy: either treat them as directories by dereferencing (find -L) or list symlinks separately. Also be mindful of locale-dependent sort order (use LC_ALL=C sort) and of exotic names (newlines in names require null-separated tools).

Testing note: run the pipeline on small sample trees, inspect the generated lists, and add quoting and set -o pipefail/set -u in scripts for safer failure handling.

Assuming I understand your problem:

find /path1 -exec basename {} \; | sort > file1
find /path2 -exec basename {} \; | sort > file2
# at this point you can use diff file1 file2
# or
# here we want files only listed in file1 but not in file2
comm -23 file1 file2
# here we show files listed in file2 but not in file1
comm -23 file2 file1
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.