I am not sure that I understand the difference between this thread and your earlier thread: Compare md5sum two servers' setup. But, whether or not they are the same topic, I don't understand why you are trying to rewrite code to perform what rsync already does??? What makes you think that rsync only compares file sizes to determine if a file has changed?
In addition: whenever you start to use expect this is the confession that something went horribly wrong in your setup.
If you plan your authorisation correctly you should never have to rely on expect (which is just a way of having passwords written in cleartext into scripts typed automatically into forms) but use (preexchanged) keys or something similar. Instead of fiddling around with expect-scripts you should simply test for a possible ssh-connection and raise an error if that doesn't work (because keys are not exchanged, are invalid or some other reason).
Here is how i do that. It first tests for IP-connectivity and then - if that is possible - for ssh-connectivity:
# ------------------------------------------------------------------------------
# f_CheckConnectivity checking connectivity for a host
# ------------------------------------------------------------------------------
# Author.....: Wolf Machowitsch
# last update: 2016 01 25 by: Wolf Machowitsch
# ------------------------------------------------------------------------------
# Revision Log:
# - 0.99 2007 01 18 Original Creation
# -
#
# - 1.00 2015 04 28 Production Version
# removed unecessary subshells
#
# - 1.01 2016 01 25 bugfix
# - changed ssh-call to cover for new hosts:
# added "-o 'CheckHostIP=no'"
# added "-o 'StrictHostKeyChecking=no'"
#
# ------------------------------------------------------------------------------
# Usage:
# f_CheckConnectivity char Hostname [ char user ]
# checks the connectivity for the host given in $1 optionally using a
# username given in $2. If no user name is given the current user is
# assumed.
#
# Example: f_CheckConnectivity $host # checks if $host can be worked on
# # using the current user (usually
# # this will be root)
#
# Prerequisites:
# - to use this function, the FPATH variable must be set
#
# ------------------------------------------------------------------------------
# Documentation:
# f_CheckConnectivity() checks in a successive manner. First an (IP)-ping
# is issued. If this is successful a connection test is done by issuing
# a command via ssh. f_CheckConnectivity() does NOT try to correct any
# errors, merely stating them.
#
# Parameters: char Host
#
# returns: 0: connectivity test passed
# 1: no ssh connection
# 2: no IP connection
# 3: parameter/other/internal error
#
# ------------------------------------------------------------------------------
# known bugs:
#
# none
# ------------------------------------------------------------------------------
# .....................(C) 2007 Wolf Machowitsch ...............................
# ------------------------------------------------------------------------------
f_CheckConnectivity ()
{
$chFullDebug
# internal variables
typeset -i iRetVal=0 # return value (see docu)
typeset chHost="$1" # hostname
typeset chUser="$2" # optional username
if [ -z "$1" ] ; then # check for prereqs
iRetVal=3
elif [ "$chUser" == "" ] ; then
chUser="$(who am i | cut -d' ' -f1)"
fi
if [ $iRetVal -eq 0 ] ; then
if ! ping -c1 $chHost 1>/dev/null 2>&1 ; then
iRetVal=2
fi
fi
if [ $iRetVal -eq 0 ] ; then
if ! ssh -nq \
-o 'BatchMode=yes' \
-o 'CheckHostIP=no' \
-o 'StrictHostKeyChecking=no' \
${chUser}@${chHost} date 1>/dev/null 2>&1; then
iRetVal=1
fi
fi
return $iRetVal
}
# --- EOF f_CheckConnectivity
Notice that you will have to adjust this if you deal with hosts in DMZs or behind firewalls, because they often block attempts to ping the host.
I had hoped that my quote from the rsync man page would encourage the OP to look farther into rsync . A more complete explanation of the workings of rsync can be found at rsync - Wikipedia, the free encyclopedia
If that is too difficult or does not meet the OP's requirements, then the MD5, sort, and compare steps seem reasonable to me.
I don't need to check connectivity but if config files are the same in certain directories. I am also not trying to sync them exactly the config files will have different IP addresses in them and different database names, this is why I can't just use rsync but was trying to hash something out that would tell me if they are different and list out the differences through making a couple of files and then doing a compare. Perhaps rsync will do this but I didn't think so.
So the script that you are hoping to create just gives you a list of files that need to be investigated further; it doesn't sync files. Isn't that exactly what:
The first time through it is likely to give you lots of false positives due to timestamp differences. But if you use rsync to synchronize those false positives (to sync the timestamps) and files that really need to be synced, subsequent runs should give you a greatly reduced list of files on which you actually need to perform your detailed md5sum checks.
And, obviously, if there are intentional IP and database name differences in some of your config files, md5sum isn't going to help you determine if there are also other differences in those files that shouldn't be present or that should cause a more complicated partial sync.
Don Cragun is right, rsync would be the solution of first choice.
But still, if this is ruled out somehow for some reason we have yet to find out:
If you do not need to check for connectivity then all the better. But in your threads title and the first post you mentioned you have to use "expect" and this can conceivably only be to transmit passwords. If you can guarantee somehow your ssh-keys can always be readily exchanged (though i'd still check that before i'd base my procedures on that) you can simply use ssh to remote-execute any command(s) you want and that would probably be a cleaner solution than using expect to initiate a pseudo-interactive ssh-session.
If you need to remotely execute arbitrary commands then you might want to do it this way (sketch):
while read HOST USER ; do
if ! ssh -nqo 'BatchMode=yes' "$USER"@"$HOST" some_command
echo "Error: some_command returned $?"
fi
done <<_EOF_
host1 user1
host2 user2
....
_EOF_
Again, I'd check if indeed the keys are exchanged by including the function i showed you and call it somewhere inside the loop as part of my errror checking, but that is up to you. You should be able to build your custom routine around the shown mechanism pretty easily.