We're an ISO27001:2013 Certified Supplier


It isn’t instinctively obvious how to compare files between two systems. For example, suppose we wanted to compare the /etc/passwd on this system with that from another system. One way of doing so is to copy the /etc/passwd file from the other system to this one, and then compare them:

$ scp othersys:/etc/passwd .
$ diff -u /etc/passwd passwd

A Quicker Way

We can do this:

$ diff -u /etc/passwd <(ssh othersys cat /etc/passwd)
--- /etc/passwd 2017-10-16 08:45:23.328047035 +0100
+++ /dev/fd/63  2017-10-18 14:50:39.393346711 +0100
@@ -15,43 +15,55 @@
 list:x:38:38:Mailing List Manager:/var/list:/usr/sbin/nologin
 gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin


Let’s break this down, starting with this part of the command:

ssh othersys cat /etc/passwd

That simply logs into othersys and writes the /etc/passwd file to stdout.

We’re perhaps used to command substitution, where the output of a command is substituted on the command line. For example:

$ echo "It's $(date +%A)!" 
It's Wednesday!

In the case of the ssh command, wrapping it in parentheses means it runs in a subshell, and the less-than arrow redirects the output of that command. This is known as process substitution.

Behind the scenes, bash sets up a file descriptor to take the output of the ssh command and feed it to diff on our command line. We can see this at the top of the diff command where the two input files are named:

$ diff -u /etc/passwd <(ssh othersys cat /etc/passwd)
--- /etc/passwd 2017-10-16 08:45:23.328047035 +0100
+++ /dev/fd/63  2017-10-18 14:50:39.393346711 +0100

Here we can see the output from the remote process being presented on /dev/fd/63.

Any command that takes file arguments can use named pipes: no temporary files or copies needed.

Could This Linux Tip Be Improved?

Let us know in the comments below.