I'm trying to compare files on the root file system with a backup, and I'd like the comparison to work a bit like git or svn diff when a file has been added or removed - That is, display the full file diff. diff unfortunately just prints a No such file or directory message, which is not very useful. I couldn't find an option for this.

The simplest workaround I could find is to parse the diff output and diff -u path <(printf '') or diff -u <(printf '') path depending on which path exists. That's a bit of a kludge - Probably 10 lines of code for what could be a simple diff option.

Another workaround is

diff -u <([ -e "$path1" ] && cat "$path1") <([ -e "$path2" ] && cat "$path2")

, but that loses the file names in the diff.

Based on Craig Sanders's answer and the previous workaround, I ended up with this:

diff -u \
    "$([ -e "$path1" ] && echo "$path1" || echo /dev/null)" \
    "$([ -e "$path2" ] && echo "$path2" || echo /dev/null)"

Edit: Turns out there is an option for it:

-N, --new-file
       treat absent files as empty

In other words:

diff -Nu "$path1" "$path2"
  • What OS/version of diff are you working with?
    – Mat
    Sep 4 '12 at 10:09
  • Ubuntu 12.04, diff (GNU diffutils) 3.2
    – l0b0
    Sep 4 '12 at 10:44

With at least some versions of GNU diffutils' diff, you can use the -N flag to do that directly (although the documentation appears to say that only works for directory diffs).

$ ls
$ cat foo
$ diff -u foo bar
diff: bar: No such file or directory
$ diff -uN bar foo
--- bar 1970-01-01 01:00:00.000000000 +0100
+++ foo 2012-09-04 12:45:34.000000000 +0200
@@ -0,0 +1 @@
$ diff -uN foo bar
--- foo 2012-09-04 12:45:34.000000000 +0200
+++ bar 1970-01-01 01:00:00.000000000 +0100
@@ -1 +0,0 @@
$ diff -v
diff (GNU diffutils) 2.8.1
Copyright (C) 2002 Free Software Foundation, Inc.
  • the man page for GNU diff 3.2 says only: -N, --new-file treat absent files as empty
    – cas
    Sep 4 '12 at 11:05
  • The version I have on hand (2.8.1) says "In directory comparison, if a file is found in only one directory, treat it as present but empty in the other directory.", so that's why I put the disclaimer. Good to know that's now documented for non-directory diffs now.
    – Mat
    Sep 4 '12 at 11:08

have you tried diff -u /dev/null filename ?

that worked for me when i just tried it.


touch missing
diff -u missing filename
rm missing

Also, if you diff directories (e.g. diff -x /path/to/backup -uN / /path/to/backup) then diff will recursively show full diffs of all files, including missing files. You need the -x, --exclude=PAT option because /path/to/backup is a subdir of /

(thanks to Mat for reminding me of the -N option)

  • thanks for the accept but i think Mat's answer is better. diff -N seems to do exactly what you want without stuffing around with tempfiles or /dev/null, and it gives you the recursive two-directory diff that i edited out of my answer because it doesn't work properly without -N
    – cas
    Sep 4 '12 at 11:02

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.