It isn’t instinctively obvious how to compare files between two systems. For example, suppose we wanted to compare the /etc/appconfig.conf
on this system with that from another system. One way of doing so is to copy the /etc/appconfig.conf
file from the other system to this one, and then compare them:
$ scp othersys:/etc/appconfig.conf /tmp $ diff -u /etc/appconfig.conf /tmp/appconfig.conf
A Quicker Way
We can do this:
$ diff -u /etc/appconfig.conf <(ssh othersys cat /etc/appconfig.conf) --- /etc/appconfig.conf 2017-10-16 08:45:23.328047035 +0100 +++ /dev/fd/63 2017-10-18 14:50:39.393346711 +0100 @@ -15,43 +15,55 @@ # Logging log-level = info +mail-log = 0 -mail-log = 1
Analysis
Let’s break this down, starting with this part of the command:
ssh othersys cat /etc/appconfig.conf
That simply logs into othersys
and writes the /etc/appconfig.conf
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/appconfig.conf <(ssh othersys cat /etc/appconfig.conf) --- /etc/appconfig.conf 2017-10-16 08:45:23.328047035 +0100 +++ /dev/fd/63 2017-10-18 14:50:39.393346711 +0100 @@ -15,43 +15,55 @@
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.