#!/bin/bash # # Compare the content of a local and a remote directories # # V0.1 - 2014-11-23 # Missing: SSH port management #------------------------------------------------------------- # Define usage #------------------------------------------------------------- usage() { cat <<-'_usage_statement_' compareDirs.sh compares the top level content of 2 local or remote directories using du. Usage: compareDirs.sh [[user@]host1:]dir1 [[user@]host2:]dir2 Note: SSH port management is missing. _usage_statement_ } #------------------------------------------------------------- # Analyse les arguments de la ligne de commande. #------------------------------------------------------------- echo -e "\n$(basename $0) $@ \n" [[ $# != 2 ]] && { usage exit -1 } function getDirFromParam { idx=`expr index "$1" ':' ` if [ $idx == 0 ] then echo $1 else echo ${1:$idx} fi } function getHostFromParam { idx=`expr index "$1" ':' ` if [ $idx != 0 ] then ((idx--)) echo ${1:0:$idx} fi } function checkHostAndDir { dir=$1 host=$2 if [ $host ] then # echo "$host - $dir --> REMOTE" if ( ! ssh $host "pwd" > /dev/null 2>&1 ) then echo "ERROR: $host unreachable!" return 1 elif ( ! ssh $host "cd $dir" > /dev/null 2>&1 ) then echo "ERROR: $dir unreachable on $host!" return 2 fi else # echo "$dir --> Local" [ -d "${dir}" ] || { echo -e "Error $dir must be a directory!" return 3 } fi return 0 } dir1=$(getDirFromParam $1) host1=$(getHostFromParam $1) dir2=$(getDirFromParam $2) host2=$(getHostFromParam $2) # echo -e "dir1 : $dir1 - host1 : $host1\ndir2 : $dir2 - host2 : $host2" checkHostAndDir "$dir1" $host1 [ $? -eq 0 ] || exit -1 checkHostAndDir "$dir2" $host2 [ $? -eq 0 ] || exit -1 #------------------------------------------------------------- # VARS #------------------------------------------------------------- tmp_report_1="/tmp/`basename $0`-local-`date +%F-%T`.log" tmp_report_2="/tmp/`basename $0`-remote-`date +%F-%T`.log" #------------------------------------------------------------- # Recupération sur erreur #------------------------------------------------------------- function traitement_erreur { echo echo "---------------------" echo ">>> Erreur $? >>>>" echo "---------------------" echo rm -f $tmp_report_1 $tmp_report_2 exit 1 } trap traitement_erreur SIGHUP SIGINT SIGTERM SIGKILL #------------------------------------------------------------- # fonction de bilan de synchro # déclarée ici pour pouvoir être utilisée par le traitement d'erreur qui suit #------------------------------------------------------------- function local_report { function numFormat { echo $1 | sed ':a;s/\B[0-9]\{3\}\>/.&/;ta' } function stats_folder() { # Attention : le nom du dossier peut contenir des blancs # il faut donc le traiter entre "" local folder="$1" local items=`find "$folder" -iname '*' | wc -l` local taille=0 echo -e " $folder" # echo -e " $(basename $folder)" if [ $items -gt 0 ]; then taille=$(du -bc "$folder" | grep total | sed -e "s/[ \t]*total/ /g") taille_f=$(numFormat $taille) items_f=$(numFormat $items) echo -e " $items_f items, $taille_f octets" else echo vide fi } local curdir=$(pwd) local dir="$(readlink -f "$1")" echo -e "LOCAL report:" echo -e "$dir" cd "$dir" for f in * ; do # Attention : le nom du dossier peut contenir des blancs # il faut donc le passer entre "" #echo "---f: $f" [ -d "$f" ] && stats_folder "$f" done echo -e "Total: " stats_folder "$dir" # echo "--- pwd: $(pwd) " cd "$curdir" echo } function remote_report { local dir="$1" local host="$2" ssh $host " function numFormat { echo \$1 | sed ':a;s/\\B[0-9]\\{3\}\\>/.&/;ta' } function stats_folder() { # Attention : le nom du dossier peut contenir des blancs # il faut donc le traiter entre \"\" local folder=\"\$1\" local items=\`find \"\$folder\" -iname '*' | wc -l\` local taille=0 echo -e \" \$folder\" if test \$items -ne 0; then taille=\$(du -bc \"\$folder\" | grep total | sed -e \"s/[ \t]*total/ /g\") taille_f=\$(numFormat \$taille) items_f=\$(numFormat \$items) echo -e \" \$items_f items, \$taille_f octets\" else echo vide fi } dir=$(readlink -f "$dir") echo \"REMOTE report: \" echo $dir cd $dir for folder in * ; do # Attention : le nom du dossier peut contenir des blancs # il faut donc le passer entre \"\" [ -d \"\$folder\" ] && stats_folder \"\$folder\" done echo -e \"Total: \" stats_folder \"$dir\" echo " } echo # set -x if [ $host1 ] then remote_report "$dir1" $host1 >> $tmp_report_1 else local_report "$dir1" >> $tmp_report_1 fi if [ $host2 ] then remote_report "$dir2" $host2 >> $tmp_report_2 else local_report "$dir2" >> $tmp_report_2 fi sdiff -atw 140 $tmp_report_1 $tmp_report_2 rm -f $tmp_report_1 $tmp_report_2