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 irc:x:39:39:ircd:/var/run/ircd:/usr/sbin/nologin gnats:x:41:41:Gnats Bug-Reporting System (admin):/var/lib/gnats:/usr/sbin/nologin +Debian-exim:x:101:103::/var/spool/exim4:/bin/false -Debian-exim:x:108:115::/var/spool/exim4:/bin/false
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
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
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.