Do not do this, it not only depends on the conditions of the race, but also [ -e /path/file ] checks if you can do stat(2) in the file, so it will return false for various reasons, not only because the file does not can exist.
An example is a symbolic link to a file that does not exist, or a file in a directory in which you do not have permission to search.
It is much better to use the right flags for the open(2) system call here, i.e. O_CREAT|O_EXCL . Thus, open() crashes if the file no longer exists, unless you need to check several millions of processor clocks earlier.
With a bourne-like shell:
if (set -C && : > "$file") 2> /dev/null; then print '%s\n' "$file has been created else print '%s\n' "It hasn't, possibly because it was already there" fi
( set -C - enable the O_EXCL flag).
Also, why do you want to create an empty file? Most likely you want to save something in this file. Then just do it:
set -C { echo blah other-commands that-generate-the-content } > "$file"
Then this group of commands is executed only if file no longer exists (and it could be created).
If you want to check for a file, write it at a minimum:
[ -e "$file" ] || [ -L "$file" ]
or
ls -d -- "$file" > /dev/null 2>&1
if you are wondering if this is a symbolic link. This will still return false if the file exists, but you do not have the right to check it.
Now, if you need a longer and more historical answer about testing file existence:
Initially, the test command (on Unix v7, where it first appeared) did not have the -e (and -h / -L ) or -a unary option) .
The way to check for the existence of a file was ls . ls (with -d ) lists the file and reports an error (and returns false exit status) if it cannot search for the file for one reason or another. Unix did not initially have symbolic links, but when they were introduced, ls was changed to make lstat(2) in the file instead of stat(2) . That is, in the case of symlink ls returns information about the symlink file, not the file in the path pointed to by the symlink.
The test (aka [ ) option for testing the file’s “existence” was first introduced into the Korn test builtin shell . It was -a , not -e . -a for accessible (I believe), which is a more accurate term than the existing one.
I do not know when or what -e entered, possibly POSIX. POSIX says that -e was chosen over -a to avoid possible confusion with the binary operator -a (for and).
In either case, both -a and -e try stat(2) in the file, not lstat(2) . I.e:
[ -e "$file" ]
equivalent to:
ls -Ld -- "$file" > /dev/null 2>&1
So, strictly speaking, it returns true, if during the test it was possible to find the path after resolving symbolic links, and if stat(2) fails, the cause of the failure is ignored.
stat can fail if the file does not exist ( ENOENT ), that is, if the file does not exist or exists, but is a symbolic link to a file that does not exist, but also for a large number of other reasons. Looking at possible error codes, stat(2) gives a few ideas:
EACCESS : during path resolution (and this can be any component of the path and the path of any symbolic link) you do not have permission to search for one component of the directory (note that you can still access the file through another path).ELOOP : ELOOP to resolve path due to too many symbolic links allowed for access.ENOTDIR . For example, to /etc/passwd/foo or a symbolic link to it.