skip to content

On Linux, what does the execute bit mean on a directory as opposed to on a regular file, and what can someone do with a directory that has x but not r?

level: middleimportance: must knowfreq 62%

answer

  1. directories are not documents
  2. x means search, not run
  3. you need the name in advance
  4. r lists, x traverses
  5. every component of the path is checked

basics

~20 s

On a directory the execute bit means search, not run: it permits resolving a name inside the directory. Read permits listing the names. With x but no r you can open a file whose exact name you already know, but ls fails.

solid answer

~50 s

On a regular file `x` means "run this as a program". On a directory it means **search** or **traverse**: permission to look a name up and to walk through the directory on the way to something deeper. `r` on a directory is what lets you enumerate the entries — that is what `ls` needs. The two are genuinely independent. A directory with mode `711` is search-only: if you already know the exact filename you can open it, but listing the directory fails with Permission denied. The reverse, `r` without `x`, is close to useless — you can read the list of names but cannot stat or open any of them, so a long listing shows question marks. And because path resolution walks component by component, you need `x` on **every** directory in the path, not just the last one. That is why one tightened parent directory can break access to a file whose own mode is wide open.

code

bash · 8 lines
bash
mkdir -p /tmp/searchonly
echo secret > /tmp/searchonly/known.txt
chmod 644 /tmp/searchonly/known.txt
chmod 711 /tmp/searchonly
# From another account: this succeeds
cat /tmp/searchonly/known.txt
# ...and this fails with Permission denied
ls /tmp/searchonly

go deeper

for a junior

Remember the one-line distinction: on a directory, execute means you may go through it and read means you may list it. Know that 755 is normal for directories and 644 for plain files.

for a middle

Explain that path resolution checks search permission on every component, and describe both asymmetric cases — 711 gives open-by-known-name without listing, while read-without-execute yields names and question marks.

for a senior

Diagnose from the symptom: given a service that hits Permission denied on a file whose mode looks fine, walk the parent chain for the service account and say why deletion is governed by the directory rather than the file.

for a principal

Own the layout convention: decide where search-only directories are the right isolation boundary versus where the group model or a stronger mechanism should carry it, and make the choice explicit so nobody re-derives it per service.

## Same letters, different meaning The nine permission bits are the same three letters everywhere, but a directory is not a document — it is a table mapping names to inodes — so the letters have to mean something different: | Bit | On a regular file | On a directory | |---|---|---| | `r` | read the contents | list the names it contains | | `w` | modify the contents | add, remove or rename entries (needs `x` too) | | `x` | execute it as a program | **search**: resolve a name inside it, traverse through it | The `x` bit on a directory is often called the *search bit* precisely to keep this distinction visible. ## Path resolution is what makes x matter When the kernel resolves `/srv/app/data/report.csv`, it walks the path one component at a time: open `/`, look up `srv` in it, look up `app` in that, and so on. At **each** directory it checks search permission for the calling process. If any single component denies `x`, resolution stops there with `EACCES`, regardless of how permissive the final file is. This is the source of one of the most common real-world confusions: a file is mode `644` and owned by the right user, yet a service still gets Permission denied. The mode on the file is fine; some parent directory is not traversable by the service account. The fix is on the directory, not the file. ## The two interesting asymmetric cases **`--x` (search but not read), typically mode 711 on a directory.** You can open `/srv/pub/known.txt` if you know that name exactly, but `ls /srv/pub` fails. This is a real, deliberate pattern: home directories are often `711` so that a web server or another user can reach an explicitly shared path inside without being able to enumerate everything the user owns. It is obscurity-flavoured rather than airtight — anyone who learns a name gets in — but it is a legitimate and widely used configuration. **`r--` (read but not search).** You can obtain the list of names, and nothing else. `ls` prints names; `ls -l` prints question marks in every column, because producing a long listing requires calling `stat` on each entry, and `stat` needs to resolve the name, which needs search permission. You cannot open any of the files either. This combination is almost never what someone intended; it usually appears after a recursive numeric chmod that stripped execute bits from directories. ## Writing a directory Creating, deleting and renaming a name requires `w` **and** `x` on the directory: write to change the table, search to resolve the name you are changing. Two consequences surprise people: ``` # You may delete a file you cannot read or write, # if you can write the directory that names it. # You may NOT delete a file you own and can write, # if the directory denies you write. ``` Deletion is a directory operation. The file's own mode says nothing about it. (World-writable shared directories carry an extra bit that restricts this, which is a separate topic.) ## Executing versus reading a program While we are on the bit: on a regular file, `x` and `r` are also independent. A compiled binary can be mode `--x` and still run — the kernel loads it, and the calling user never gets to read the bytes. A **script** is different: the kernel hands it to the interpreter named on the `#!` line, and that interpreter opens the file normally, so a script needs both read and execute for the invoking user. ## How this shows up in an interview The question is usually phrased as a symptom: "a process can `cat` a file by full path but `ls` on its directory fails", or "we chmod'd everything to 644 and now nothing works". Both are the same fact seen from two sides — directories need their execute bit, and losing it breaks traversal while leaving the file modes untouched and innocent-looking. A good answer names the bit's directory meaning, states that every path component is checked, and gives one concrete configuration (`711` for search-only, `755` for the normal readable-and-traversable case, `750` when only the group should reach it).

  • A service can read a file when you test it by full path as root, but the service account gets Permission denied. Where do you look first?
    At the directories above the file, not at the file. Walk each component from the root and check search permission for the service account — `namei -l` on the full path renders the whole chain at once. A single parent missing `x` for that user or group breaks resolution while every mode you inspect on the file itself looks correct.
  • Why does `ls -l` show question marks for entries in some directories?
    Because you have read permission on the directory but not search. Read lets `ls` enumerate names, but filling in the size, mode and owner columns requires a `stat` call on each entry, and that resolves the name — which needs the execute bit. So you get names and nothing else.
  • Can a binary be executed by someone who cannot read it?
    Yes for a compiled binary: mode `--x` is enough, because the kernel maps the executable itself and the user never reads the bytes through the filesystem. A script is different — the kernel starts the interpreter from the `#!` line, and that interpreter opens the file as an ordinary read, so scripts need both read and execute.

Read on a directory is the index in a library catalogue; execute is the pass that lets you walk into the stacks. With the pass but no catalogue you can fetch a book whose shelf number you already know, and with the catalogue but no pass you can only read titles.

saying these in an interview costs you the question

  • Saying the execute bit on a directory means you can run the directory
  • Assuming only the final directory in a path is permission-checked
  • Believing read permission alone is enough to open files inside a directory
  • Setting directories to 644 in a recursive chmod and expecting access to work
  • Claiming you can never delete a file you lack write permission on

context