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
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
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
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.