107

I wanted to be clever and compare a remote file to a local file without first manually downloading it. I can get the contents of the remote file by

ssh user@remote-host "cat path/file.name"

However, piping that to diff

ssh user@remote-host "cat path/file.name" | diff path/file.name

gives me this:

diff: missing operand after `path/file.nae'
diff: Try `diff --help' for more information.

I have ssh keys set up, so it's not prompting me for a password. What's a workaround for this?

3
  • 6
    By the way, you're still downloading the file when you do this (since its content gets sent over the SSH connection), you're just not saving it anywhere. So it's not like you save any bandwidth or anything.
    – David Z
    Aug 21, 2010 at 0:13
  • 3
    Yeah, I just don't want to muck up my file system with one-shot files hanging around.
    – user394
    Aug 23, 2010 at 13:29
  • 2
    for when the command does not support stdin (e.g. via -), you can use /dev/stdin. e.g. diff file1 /dev/stdin Mar 15, 2017 at 19:46

4 Answers 4

127

Use - to represent the standard input:

ssh user@remote-host "cat path/file.name" | diff path/file.name -
1
  • 2
    What if both files are fetched via ssh?
    – prasanthv
    Mar 4 at 16:47
83

Here's one workaround: diff seems to accept <(expr) as arguemnts:

diff <(ssh \"cat path/file.name/") <(cat path/file.name)
6
  • 23
    That's not diff, that's the shell (bash, ksh and zsh support this syntax, but it's not POSIX), with some help from the kernel (it must provide /dev/fd: diff sees something like /dev/fd/3 on its command line). Aug 20, 2010 at 19:25
  • 4
    It doesn't "must provide" - shells can create temporary named pipes for this feature too.
    – ephemient
    Sep 24, 2010 at 14:11
  • 4
    this is the coolest answer!
    – neves
    Dec 20, 2011 at 21:47
  • 9
    I personally prefer this answer. I needed to diff two different XML files; but they needed to be properly formed first. That led to this: diff -y <(xmllint --format "${1}") <(xmllint --format "${2}") which I now use all the time. Oct 8, 2014 at 19:49
  • 1
    This is also very useful on OS X where one might want to compare two binary .plist files: diff <(plutil -convert xml1 -o -- "${1}") <(plutil -convert xml1 -o - -- "${2}")
    – morgant
    Feb 16, 2015 at 18:57
3

Piping into diff is equivalent to running

diff path/file.name

and then, once it's running, typing the entire contents of the file.

As you can see, that's not what you expected.

2
  • No workaround? :(
    – user394
    Aug 20, 2010 at 18:56
  • 1
    Look at Hemant's answer. I didn't know of one.
    – Macha
    Aug 20, 2010 at 18:59
1
diff /tmp/localtempfile <(ssh -A -o StrictHostKeyChecking=no root@server "cat /tmp/remotetempfile")
1
  • 1
    What is with the lowering of security StrictHostKeyChecking=no? Otherwise a good answer. Mar 15, 2017 at 19:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.