For the following demonstration, I created a few directories:
$ mkdir read_only
$ mkdir exec_only
$ mkdir r_e
$ touch read_only/cant_open
$ echo foo > read_only/cant_open
$ echo bar > exec_only/cant_find
$ echo baz > r_e/normal
$ chmod 400 read_only/
$ chmod 100 exec_only/
$ chmod 500 r_e/
Read permissions are sufficient to list the contents of the directory: ls(1)
can't find details about the file, but it can tell you the name of the file.
$ ls read_only/
ls: cannot access read_only/cant_open: Permission denied
cant_open
But read-only access doesn't let you traverse the directory:
$ cat read_only/cant_open
cat: read_only/cant_open: Permission denied
Execute permissions are sufficient to traverse the directory (including cd
), but you can't list the contents:
$ ls exec_only/
ls: cannot open directory exec_only/: Permission denied
Even though you can't get a listing of files in the directory, you can still traverse the directory:
$ cat exec_only/cant_find
bar
Both read and execute permissions work as you expect:
$ ls r_e
normal
$ cat r_e/normal
baz
While it is initially confusing to have permission to list the files in a directory but not be able to do anything with them, and it is also confusing to have permission to do things with files but not be able to list them, it is part of Unix's tradition of simple mechanisms being used for clever things: these two elements alone make it easy to implement Capability-based security. If I were to place a few thousand files in the directory, but only wanted some people to read files meant for them, I could easily pick unguessable filenames, and give out the filenames when people give me money to read the files. :)
Or, maybe you have a dozen clients, and you want them all to have access to a directory of files meant for them. If you place all the client information into a single directory with only execute access, they could never determine your other clients, unless they already know that the other person is a client.