Comparing files on different servers

@igor_sarcevic ·

Let’s say you have two servers named gandalf and charmander, and a configuration file config.xml that should be present on each server. Due to some human error the files got different and your servers started to act weird. It would be nice to compare them and find out what part of them is different.

Luckily, you have ssh access to both servers. A simple solution is to scp both file to a local temp file and compare them with diff.

scp gandalf:~/config.xml /tmp/gandalf_config.xml
scp charmander:~/config.xml /tmp/charmander_config.xml
diff /tmp/gandalf_config.xml /tmp/charmander_config.xml

The above works like a charm, but can we do it in fewer steps? Well, if the files are not gigantic we can use the <( command ) pattern to compare them without temp files.

diff <(ssh gandalf "cat ~/config.xml") <(ssh charmander "cat ~/config.xml")

This technique is called Process substitution and can have even more powerful use cases.

Scaling the issue

But what if we have more than two servers, lets say a hundred, and we want to check whether we have the same configuration file on every one of them?

A good server naming scheme combined with a for loop can help us a lot. A good naming scheme can be to replace special names like gandalf and charizard with a baring yet wastly more handy form like the following:

s1, s2, ... s100

First, let’s save a local copy of a good configuration file:

scp s1:~/config.xml /tmp/good

To compare this file with a remote file we can use the above scheme:

diff /tmp/good <(ssh s2 "cat ~/config.xml")

and loop through all the servers with a nifty for loop:

for i in {2..100}; { diff /tmp/good <(ssh "s$i" "cat ~/config.xml") }