2つのディレクトリを比較するスクリプト

スクリプト名: DirCmp.sh
書式: DirCmp.sh [-v] [dir1] dir2
目的: 2つのディレクトリ下のファイル構成を比較する
1.1番目のディレクトリ下にあって、2番目のディレクトリ下にはないファイル
2.2番目のディレクトリ下にあって、1番目のディレクトリ下にはないファイル
3.両方のディレクトリにはあっても、名前が同じだけで実体が異なるファイル
-v 詳細表示オプション
同じ名称のファイルがあって中身が異なっている場合
ファイルの何行目がどのように異なっているか表示する
戻り値: 2つのディレクトリのファイル構成が等しい場合:0
使用方法の誤りか何らかのエラーで終了した場合:1
2つのディレクトリのファイル構成が異なっていた場合:2

#!/bin/sh
CMDNAME=`basename $0`
USAGE="Usage: $CMDNAME [-v] [dir1] dir2"
CURDIR=`pwd`
DIR1=
DIR2=
DIR1_FILES=/tmp/files1.$$
DIR2_FILES=/tmp/files2.$$
ALL_FILES=/tmp/allfiles.$$
COMMON_FILES=/tmp/comfiles.$$
TMP=/tmp/tmp.$$
FOUND=FALSE
FIRST=
VERBOSE=FALSE

trap 'rm -f /tmp/*.$$; exit 1' 1 2 3 15

#オプションの処理
while :; do
    case $1 in
        -v)  VERBOSE=TRUE
             shift
             ;;
        --)  shift
             break
             ;;
        -*)  echo "$USAGE" 1>&2
             exit 1
             ;;
        *)   break
             ;;
    esac
done

#コマンド行に指定された引数のチェック
if [ $# -eq 1 ]; then
    DIR1="."
    DIR2="$1"
elif [ $# -eq 2 ]; then
    DIR1="$1"
    DIR2="$2"
else
    echo "$USAGE" 1>&2
    exit 1
fi

#指定された引数がディレクトリかどうかのチェック
if [ ! -d $DIR1 ]; then
    echo "$DIR1 is not a directory." 1>&2
    exit 1
fi
if [ ! -d $DIR2 ]; then
    echo "$DIR2 is not a directory." 1>&2
    exit 1
fi

#それぞれのディレクトリのファイル構成を求める
cd $DIR1
find . \( -type f -o -type l \) -print | sort > $DIR1_FILES
cd $CURDIR
cd $DIR2
find . \( -type f -o -type l \) -print | sort > $DIR2_FILES
cd $CURDIR

#両方に含まれる全ファイルのリスト
#両方に重複して含まれるファイルのリストを作成
cat $DIR1_FILES $DIR2_FILES | sort | uniq    > $ALL_FILES
cat $DIR1_FILES $DIR2_FILES | sort | uniq -d > $COMMON_FILES

#2番目のディレクトリ下にはあっても
#1番目にはないファイルのリストを表示
cat $DIR1_FILES $ALL_FILES | sort | uniq -u > $TMP
if [ -s $TMP ]; then
    FOUND=TRUE
    echo ""
    echo "Files missing from $DIR1:"
    for f in `cat $TMP`; do
        f=`expr $f : '..\(.*\)'`
        echo "  $f"
    done
fi

#1番目のディレクトリ下にはあっても
#2番目にはないファイルのリストを表示
cat $DIR2_FILES $ALL_FILES | sort | uniq -u > $TMP
if [ -s $TMP ]; then
    FOUND=TRUE
    echo ""
    echo "Files missing from $DIR2:"
    for f in `cat $TMP`; do
        f=`expr $f : '..\(.*\)'`
        echo "  $f"
    done
fi

#両方のディレクトリにはあるが
#名称が同じで中身が異なるファイルのリストを作成
FITST=TRUE
for f in `cat $COMMON_FILES`; do
    cmp -s $DIR1/$f $DIR2/$f
    if [ $? -ne 0 ]; then
        FOUND=TRUE
        f=`expr $f : '..\(.*\)'`
        if [ "$FIRST" = "TRUE" ]; then
            FIRST=FALSE
            echo ""
            echo "Files that are not the same:"
        fi
        if [ "$VERBOSE" = "TRUE" ]; then
            echo ""
            echo "File: $f"
            diff $DIR1/$f $DIR2/$f
        else
            echo "  $f"
        fi
    fi
done

rm -f /tmp/*.$$
if [ $FOUND = TRUE ]; then
    exit 2
else
    echo "The directories are the same."
    exit 0
fi