Linux Directory Permissions

Read, write and execute permissions are used for directories as well as files on Linux but their meaning for directories is not as straight forward1.

The permissions needed for each action are:

Action Required Permission(s)
Listing the entries of the directory Read
Adding or removing entries from the directory Write and Execute (see also "Restricted Deletion" below)
"cd" into the directory Execute
Accessing the directory entries' contents or entry metadata Execute
Modifying the directory entries' contents or entry metadata Execute
Remove the directory. As with normal files, the permissions of the parent directory and not the directory itself determine if you can remove it. The directory must be empty.

Or listed inversely each permission allows:

Permission Symbol Value Description for directories
Read r 4 Allows listing the names of entries in the directory (e.g. using "ls") but not entry metadata or contents.
Write w 2 Allows adding, removing or moving entries (but not their contents).
Execute x 1 Allows accessing and modifying the entry contents and metadata. Also needed to add, delete or remove entries. Also called "Search" for directories2.

Playground

See how the following commands are handled when executed on a directory named testdir that starts with a single file named A.txt when the executing user has the permissions you choose:

Toggle permissions:
$ chmod u= testdir
$ stat testdir
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0000/d---------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0100/d--x------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0200/d-w-------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0300/d-wx------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0400/dr--------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0500/dr-x------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0600/drw-------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
File: testdir Size: 4096 Blocks: 8 IO Block: 4096 directory Device: 254,0 Inode: 57417470 Links: 2 Access: (0700/drwx------) Uid: ( 1000/ ben) Gid: ( 1000/ ben) Access: 2030-01-01 08:30:00.000000000 -0000 Modify: 2030-01-01 08:30:00.000000000 -0000 Change: 2030-01-01 08:30:00.000000000 -0000 Birth: 2030-01-01 08:30:00.000000000 -0000
$ ls -l testdir
ls: cannot access 'testdir/A.txt': Permission denied total 0 -????????? ? ? ? ? ? A.txt
ls: cannot open directory 'testdir': Permission denied
total 4 -rw-r--r-- 1 ben ben 12 Oct 12 2022 A.txt
$ cat testdir/A.txt
Lorem Ipsum
cat: testdir/A.txt: Permission denied
$ echo "New file" > testdir/B.txt
bash: line 1: testdir/B.txt: Permission denied
$ cd testdir
bash: line 1: cd: testdir: Permission denied

Examples explained

More advanced permissions


1. This article is focused on directory permissions. For an intro to Linux permissions in general you can read this Linux Foundation article, this article, the chmod man page or search for more.

2. The chmod man page is the main source of this page's information.

3. See this SO question. I like the OPs analogy of "execute" permitting access to inodes.


Written by Ben Hansen on 2022-10-04. Feedback and edit suggestions are appreciated.