84

There are two switches for the if condition which check for a file: -e and -f.

What is the difference between those two?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Ahatius
  • 4,777
  • 11
  • 49
  • 79
  • @jww It's a question about the if block in bash scripting - it might not be a programming language, but I sure wouldn't call it off topic. – Ahatius Jun 23 '16 at 13:20
  • Fair enough. You had it tagged as such; so you moved it towards programming and away from "how do I use this command". Retracted. – jww Jun 23 '16 at 15:57

4 Answers4

117

See: http://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html

I believe those aren't "if switches", rather "test switches" (because you have to use them inside [] brackets.

But the difference is:

[ -e FILE ] True if FILE exists.

This will return true for both /etc/hosts and /dev/null and for directories.

[ -f FILE ] True if FILE exists and is a regular file. This will return true for /etc/hosts and false for /dev/null (because it is not a regular file), and false for /dev since it is a directory.

rogerdpack
  • 62,887
  • 36
  • 269
  • 388
Emil Vatai
  • 2,298
  • 1
  • 18
  • 16
  • 3
    Directories are probably the most common things you'll encounter in the file system that aren't regular files. – Keith Thompson Jan 01 '20 at 00:58
  • 1
    Just my two cents, -e will output true with symlinks, that might come in handy when you want to validate that a file exists whether it's a directory, a symlink, or a regular file. – Julien B. Nov 11 '20 at 19:46
56
$ man bash

       -e file
              True if file exists.
       -f file
              True if file exists and is a regular file.

A regular file is something that isn't a directory, symlink, socket, device, etc.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
jman
  • 11,334
  • 5
  • 39
  • 61
  • Thanks for the answer. Guess this means that for -f to become true, you have to reference to a file which isn't a link or something like that? – Ahatius Apr 18 '12 at 07:12
  • Yes. They typically have a `-` in the first character of ls -l output. – jman Apr 18 '12 at 07:13
  • 1
    @Garrett Same for CentOS 6.9. – sevenOfNine Mar 20 '18 at 08:49
  • 1
    The reason why test command with `-f` returns true for symbolic link is answered by nos at https://stackoverflow.com/questions/49380068/what-is-the-regular-file-on-centos-and-ubuntu – sevenOfNine Mar 23 '18 at 10:09
7

The if statement actually uses the program 'test' for the tests. You could write if statements two ways:

if [ -e filename ];

or

if test -e filename;

If you know this, you can easily check the man page for 'test' to find out the meanings of the different tests:

man test
gitaarik
  • 42,736
  • 12
  • 98
  • 105
6

-e checks for any type of filesystem object; -f only checks for a regular file.

Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358