I created a directory d and a file f inside it. I then gave myself only read permissions on that directory. I understand this should mean I can list the files (e.g. here), but I can't.

will@wrmpb /p/t/permissions> ls -al
total 0
drwxr-xr-x   3 will  wheel  102  4 Oct 08:30 .
drwxrwxrwt  16 root  wheel  544  4 Oct 08:30 ..
dr--------   3 will  wheel  102  4 Oct 08:42 d
will@wrmpb /p/t/permissions> ls d
will@wrmpb /p/t/permissions>

If I change the permissions to write and execute, I can see the file.

will@wrmpb /p/t/permissions> chmod 500 d
will@wrmpb /p/t/permissions> ls d
will@wrmpb /p/t/permissions> 

Why is this? I am using MacOS.

Edit: with reference to @ccorn's answer, it's relevant that I'm using fish and type ls gives the following:

will@wrmpb /p/t/permissions> type ls
ls is a function with definition
function ls --description 'List contents of directory'
    command ls -G $argv
  • The duplicate doesn't answer the question. It implies that you can do the thing that I demonstrate you can't. @ccorn's answer is perfect. – wrgrs Oct 4 '17 at 15:58
  • Wow, the Fish thing is a rather important piece of (initially) missing information. – Stephen Kitt Oct 4 '17 at 16:03
  • Yes you're right, I should have added it, but it looks like the same thing would happen in bash if you alias ls='ls -G', which I think many people do. – wrgrs Oct 4 '17 at 16:07
  • Does for me. Are you on MacOS? Maybe there's another question here. Edit: yep, I get different behaviour on Linux. – wrgrs Oct 4 '17 at 16:21

Some preparations, just to make sure that ls does not try more things than it should:

$ unalias ls 2>/dev/null
$ unset -f ls
$ unset CLICOLOR

Demonstration of the r directory permission:

$ ls -ld d
dr--------  3 ccorn  ccorn  102  4 Okt 14:35 d
$ ls d
$ ls -l d
ls: f: Permission denied
$ ls -F d
ls: f: Permission denied

In traditional Unix filesystems, a directory was simply a list of (name, inode number) pairs. An inode number is an integer used as index into the filesystem's inode table where the rest of the file metadata is stored.

The r permission on a directory allows to list the names in it, but not to access the information stored in the inode table, that is, getting file type, file length, file permissions etc, or opening the file. For that you need the x permission on the directory.

This is why ls -l, ls -F, ls with color-coded output etc fail without x permission, whereas a mere ls succeeds.

The x permission alone allows inode access, that is, given an explicit name within that directory, x allows to look up its inode and access that directory entry's metadata:

$ chmod 100 d
$ ls -l d/f
-rw-r--r--  1 ccorn  ccorn  0  4 Okt 14:35 d/f
$ ls d
ls: d: Permission denied

Therefore, to open a file /a/b/c/f or list its metadata, the directories /, /a, /a/b, and /a/b/c must be granted x permission.

Unsurprisingly, creating directory entries needs both w and x permissions:

$ chmod 100 d
$ touch d/g
touch: d/g: Permission denied
$ chmod 200 d
$ touch d/g
touch: d/g: Permission denied
$ chmod 300 d
$ touch d/g

Wikipedia has a brief overview in an article on file system permissions.

  • Amazing. /bin/ls d shows the contents for me. Thanks! – wrgrs Oct 4 '17 at 15:55
  • OK, so it was a redefinition issue (with -G for colorized output, which needs metadata, thus x perms). Therefore my preparations with unalias ls and unset CLICOLOR. I should have added unset -f ls to remove any such function definition as well. Edited. – ccorn Oct 4 '17 at 16:51
  • More wiki ressources: wiki.archlinux.org/index.php/File_permissions_and_attributes – loxaxs Oct 28 '17 at 18:19

To read a directory you also need to be able to traverse into it (the x bit). So, at minimum you need r-x for a directory to be able to access it in any way.

  • 2
    No, you don’t; ls should still be able to list the files in the directory, even if the directory isn’t executable. – Stephen Kitt Oct 4 '17 at 8:22
  • You can leave the read permission off. You will then be able to access the files but not to list the directory's contents. – Kusalananda Oct 4 '17 at 8:24
  • @Kusalananda - good point, indeed I use this from time to time. – Soruk Oct 4 '17 at 8:52
  • @Stephen Kitt - Maybe it SHOULD, but the implementation is that it doesn't. – Soruk Oct 4 '17 at 8:53
  • 1
    @Soruk and so the question remains: why doesn’t it? – Stephen Kitt Oct 4 '17 at 8:55

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.