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.


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 -
  • Ah, you are good, indeed, I didn't check if sh is bash or not. Thank you very much for the solution. – greenoldman Apr 21 '11 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 '18 at 21:49
  • @Nakilon You would just change the argument order: diff - file1. – Caleb Jan 5 '18 at 6:53
  • Cool. This didn't work for git diff. – Nakilon Jan 6 '18 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 '18 at 12:45

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.

  • That's not a function, it's a block, and it doesn't make any difference. – Gilles 'SO- stop being evil' Apr 20 '11 at 23:05
  • @gilles Thx for the correction. BTW I've tried myself and it works. Did you? – tmow Apr 21 '11 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. – Gilles 'SO- stop being evil' Apr 21 '11 at 6:51
  • 1
    @gilles ok, thx for the explanation. – tmow Apr 26 '11 at 12:38

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.