ssh username@ServerIP 'ls -1 /tmp' | diff <(ls -1 /tmp)
Today I ran into quite the conundrum. I’ve been needing to compare the contents of a file on a remote server with the contents of a file on my local server over ssh. My original solution was to copy the file from one server to the other over sftp and compare their contents with diff.
However, when you need to compare more than just the contents of a file, things can get really messy. Take for instance another situation where I needed to compare the contents of a directory. First, I needed to output the contents of a directory on BOTH servers into two files I had to create. Then I had to sftp into one server, copy it over to the other server, and run diff to compare their contents. Talk about complicated, yeah?
All this copying and sftp-ing around frustrated me to the point where I wanted to find another solution. Sadly, my solution is a bit complicated for someone who doesn’t know the linux command line super well, but at least it works and it works fast. I’ll go slowly because if I don’t, I won’t get it myself either.
ssh username@ServerIP 'ls -1 /tmp' | diff <(ls -1 /tmp)
Here’s our example. The end result of this example is to get a comparison of the contents of a remote /tmp directory and the contents of our local /tmp directory.
First things first, we have to run a command remotely to get the contents of said remote directory. To do this, we run simply
ssh username@ServerIP 'ls -1 /tmp'
That gets a list of the files and folders in the /tmp directory. Specifically, the -1 switch gives us one file or folder per line.
Next up we pipe that into the diff command.
For those of you who may not know about this functionality, piping basically takes the output of one command, and feeds it to another. In this case, we are taking the listed contents of a remote directory and feeding it to the diff command. Now, we do this by using the following.
... | diff ...
Basically, the diff command works by finding the difference between the first thing it is given and the second thing it is given. Generally speaking, diff works like the following.
diff <file1> <file2>
In this case we are saying diff which means to substitute what was piped in with the -.
Up to this point, we have the contents of our remote directory and we have run the diff command. All we need now is to give it the second input to compare our first to. This brings us to our final step getting the contents of a local directory.
This is about one of the most common linux command line functions performed. However, due to the fact that we want to compare the contents of the directory with the contents of another directory, things get a bit more complicated sadly. Do accomplish this, we need to run a nested command.
Ordinarily running ls -1 /tmp after a diff command would result in an error rather than giving us what we want. To substitute a command for a file and so compare the command’s output, we need to encase it in <(). Our final piece of the command should look like this.
<(ls -1 /tmp)
This completes our command. If you try to run the entire thing, you should be asked for your password to the remote server. Upon entering your password, the command should run as expected, comparing the files and folders in the two directories.
The final command again looks like this…
ssh username@ServerIP 'ls -1 /tmp' | diff <(ls -1 /tmp)
If you want to get really tricky, you can compare the contents of a remote file and the contents of a local file. We’ll take httpd.conf for instance.
ssh username@ServerIP 'cat /etc/httpd/conf/httpd.conf' | diff <(cat /etc/httpd/conf/httpd.conf)
Hopefully that description wasn’t too confusing. It’s a complicated command to run (probably the worst I have ever used actually), but with some practice, it should become pretty easy if you understand how it works.
Let me know if I didn’t describe anything well enough and I will do my best to help out and update the post so it is more user friendly.
Thanks for reading!
Category:Linux Category:SSH