52

Normally you would write:

diff file1 file2

But I would like to diff a file and output from the command (here I make command a trivial one):

diff file1 <(cat file2 | sort)

Ok, this work when I enter this manually at shell prompt, but when I put exactly the same line in shell script, and then run the script, I get error.

So, the question is -- how to do this correctly?

Of course I would like avoid writing the output to a temporary file.

2 Answers 2

60

I suspect your script and your shell are different. Perhaps you have #!/bin/sh at the top of your script as the interpreter but you are using bash as your personal shell. You can find out what shell you run in a terminal by running echo $SHELL.

An easier way to do this which should work across most shells would be to use a pipe redirect instead of the file read operator you give. The symbol '-' is a standard nomenclature for reading STDIN and can frequently be used as a replacement for a file name in an argument list:

cat file2 | sort | diff file1 -

Or to avoid a useless use of cat:

sort < file2 | diff file1 -
5
  • Ah, you are good, indeed, I didn't check if sh is bash or not. Thank you very much for the solution. Apr 21, 2011 at 10:04
  • It is diffing file with stdout. Now how to diff stdout with a file? I mean, the opposite direction. it's -R in case of using git diff --no-index
    – Nakilon
    Jan 4, 2018 at 21:49
  • @Nakilon You would just change the argument order: diff - file1.
    – Caleb
    Jan 5, 2018 at 6:53
  • Cool. This didn't work for git diff.
    – Nakilon
    Jan 6, 2018 at 4:49
  • @Nakilon Of course not, why would it? git diff is a completely different beast and operates on references to glob objects in its internal index, not files; diff operates on the file system. The - syntax is just shell syntactic sugar for /dev/stdin, the file representing the STDIN stream. Hence why diff can use it as a substitute for a file name. Meanwhile git diff isn't looking for files, it's looking up objects so you have to pass it something it recognizes. Don't use it to compare files to each other, use diff for that.
    – Caleb
    Jan 9, 2018 at 12:45
-3

The scope of the standard input it's the script itself, so just put your code inside a blocku like this:

{
  diff file1 <(sort file2)
}

In this way the scope of the STDIN it's inside the block..

I've tried and it works.

4
  • That's not a function, it's a block, and it doesn't make any difference. Apr 20, 2011 at 23:05
  • @gilles Thx for the correction. BTW I've tried myself and it works. Did you?
    – tmow
    Apr 21, 2011 at 6:09
  • 3
    The block doesn't have any effect on the validity of the <(…) construct. Your script will work or not work depending on whether you run it in a shell that supports <(…) or not (ksh93/bash/zsh vs Bourne/ash/kshk88). Caleb's answer nails it all. Apr 21, 2011 at 6:51
  • 1
    @gilles ok, thx for the explanation.
    – tmow
    Apr 26, 2011 at 12:38

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .