diff remote files
Jun 7th, 2007 by dmess0r
Have you ever had the need to run diff(1) against two files, which existed on two separate remote machines?
For example, I am on host A, and I want to check and see if there are any differences between hostB:/tmp/foo.conf and hostC:/tmp/foo.conf.
Traditionally one would need to log into one of those systems, and copy the files locally, and run a diff against the two to see the changes.
Thanks to a fun I/O trick in bash (and I am sure other shells as well) we can perform a diff without needing to copy the files anywhere.
Try this on for size:
hostA$ diff -u <(ssh -n hostB cat /tmp/foo.conf) <(ssh -n hostC cat /tmp/foo.conf)
Using the unified output format (my personal favorite), from hostA, we are able to see if there are any differences between the two configs on remote machines. Neat eh?
So what does it look like when you have a difference in output? It is a little misleading at first.. lets see what it looks like:
hostA$ diff -u <(ssh -n hostB cat /tmp/foo.conf) <(ssh -n hostC cat /tmp/foo.conf)
— /dev/fd/63 2007-06-07 12:31:29.144933535 -0700
+++ /dev/fd/62 2007-06-07 12:31:29.148933079 -0700
@@ -1 +1 @@
-top secret text
+less than secret text
Notice the /dev/fd/6[23] bit? Bash allocates a file descriptor when you perform the redirect. We use the -n flag on ssh to prevent a read of stdin, and then we execute the command dump the output to stdout (and to the fd). Then, we diff the output from each fd as if it were a local file, which is exactly what is required by diff(1).
Now if there is no difference, there will be nothing produced in the output, just like how diff(1) normally behaves.