How to tell the difference between "No such file or directory" and "Permission Denied"

Solution 1:

Test the file instead.

test -e /etc/shadow && echo The file is there

test -f /etc/shadow && echo The file is a file

test -d /etc/shadow && echo Oops, that file is a directory

test -r /etc/shadow && echo I can read the file

test -w /etc/shadow && echo I can write the file

See the test man page for other possibilities.

Solution 2:

$ test -f /etc/passwd
$ echo $?
0

$ test -f /etc/passwds
$ echo $?
1

Solution 3:

The other answers don't really distinguish between the different cases, but this perl script does:

$ cat testscript
chk() {
   perl -MErrno=ENOENT,EACCES -e '
      exit 0 if -e shift;        # exists
      exit 2 if $! == ENOENT;    # no such file/dir
      exit 3 if $! == EACCES;    # permission denied
      exit 1;                    # other error
   ' -- "$1"
   printf "%s %s  " "$?" "$1"
   [[ -e "$1" ]] && echo "(exists)" || echo "(DOES NOT EXIST)"
}
chk /root
chk /etc/passwd/blah
chk /x/y/z
chk /xyz
chk /root/.profile
chk /root/x/y/z

$ ./testscript
0 /root  (exists)
1 /etc/passwd/blah  (DOES NOT EXIST)
2 /x/y/z  (DOES NOT EXIST)
2 /xyz  (DOES NOT EXIST)
3 /root/.profile  (DOES NOT EXIST)
3 /root/x/y/z  (DOES NOT EXIST)

See the stat(2) manpage for possible error codes.