A file has mode 644, so why can't you delete it? A directory has read permission, so why can't you enter it? Understanding permissions takes more than memorizing 4, 2, and 1. You must also consider whether a permission applies to file contents, directory entries, or the path used to reach them.
First, read the entire ls -l line#
ls -l -- example.txt
ls -lh -- example.txt
ls -ld -- project project/docsThe first command displays a long listing, while -h uses human-readable size units. -d shows the directory itself rather than listing the entries inside it. The third form is particularly useful when checking directory permissions.
-rw-r----- 1 alice editors 2048 Oct 8 10:30 example.txtThis is a fictional example line. In order, it shows the type and mode bits, hard-link count, owner, group, size, time, and name. Here, alice is the owner and editors is the group; that does not mean only two people can use this file. A directory's size generally reflects its own data structure, rather than the sum of all the files it contains. Nor can the hard-link count be directly converted into a subdirectory count on every filesystem. [1]
| Marker | Meaning |
|---|---|
- | Regular file |
d | Directory |
l | Symbolic link |
b | Block device |
c | Character device |
s | Socket |
p | Named pipe (FIFO) |
The mode displayed for a symbolic link is not the target file's actual access permissions. When accessing content through a link, check the target and the path leading to it as well. If extra markers appear in a long listing, interpret them according to the tool and platform; do not try to explain every character as one of the nine mode bits.
Three rwx groups, eight numeric combinations#
The type marker is followed by three permission groups: u for the owner, g for the group, and o for other users. Within each group, the order is read, write, execute; a dash marks an absent permission. In chmod's symbolic notation, a means to operate on all three groups together.
Each permission group combines binary bits: read is 4, write is 2, and execute is 1. Adding them produces an octal digit. The three digits set u, g, and o respectively; their order matters.
| Number | Symbols | Combination |
|---|---|---|
| 0 | --- | None |
| 1 | --x | Execute |
| 2 | -w- | Write |
| 3 | -wx | Write + execute |
| 4 | r-- | Read |
| 5 | r-x | Read + execute |
| 6 | rw- | Read + write |
| 7 | rwx | Read + write + execute |
Thus, 755 gives the owner read, write, and execute permissions, and the other two groups read and execute; 644 gives the owner read and write, and the others read; 600 retains read and write for the owner only. The following examples contrast numeric settings with symbolic additions and removals. Choose individual lines according to your actual needs:
chmod 755 script.sh
chmod 644 notes.txt
chmod 600 private-key.example
chmod u+x script.sh
chmod g-w notes.txt
chmod o-rwx notes.txt
chmod a+r notes.txtNumeric notation specifies the entire set of ordinary permissions, while symbolic notation is useful for adjusting only part of it. a+r adds read permission for all three groups, not “read permission only for me.” Changing a mode generally requires ownership or the appropriate privilege. Owner and group changes are handled by chown and chgrp, subject to their respective permission requirements. Who owns a file and what mode it has are two different questions.
Do not treat 777 as a universal fix. It grants all ordinary permissions to all three groups, but may still fail to address a read-only mount, ACLs, security modules, or path components. It can also grant write access to people who should not be able to modify the contents.
x on a directory means search and traversal#
| Permission | Regular file | Directory |
|---|---|---|
r | Read file contents | Read the list of names in the directory |
w | Modify file contents | Modify directory entries; common operations also require x |
x | One necessary condition for execution as a program | Search the directory, resolve paths inside it, and traverse it |
With r but no x on a directory, you may be able to list names without being able to retrieve entry details or access their contents. With x but no r, you may be unable to browse the names, yet still access a target if you know its exact name and the subsequent access is also permitted.
cd requires the necessary search permissions on the target directory and the path prefix; it does not require r to list the names first. Conversely, even if a file itself is readable, access still fails if a directory along the path lacks x. [3]
Having x on a file does not guarantee successful execution either: its format, interpreter path, mount options, and other factors still matter. For a script, ./script.sh and explicitly asking an interpreter to read it with sh script.sh also access it differently. A single character cannot establish that a program will run.
To delete a name, check its parent directory first#
Deletion usually removes an entry from its parent directory; it does not first erase the file's contents character by character. Being able to write to a file therefore does not mean you can delete it. Conversely, a file's lack of write permission does not necessarily prevent its removal from a parent directory that allows modification.
A typical unlink operation requires write and search permissions on the parent directory, along with compliance with restrictions such as the sticky bit. A read-only filesystem, immutable attributes, or additional access controls may also deny the operation. Renaming across directories requires considering all the directories involved, rather than looking only at the file's rwx line. [4]
To change a file's contents, check the file. To change its name or location within a directory, check the directory. To access either, check the entire path as well.
s, S, t, T: special bits share the execute positions#
Special bits are displayed in the execute-bit positions. The SUID bit appears in the owner's execute position, the SGID bit in the group's, and the sticky bit in the others' position. A lowercase s or t means the corresponding execute bit is also set; an uppercase S or T means the special bit is set but the corresponding execute bit is not. Uppercase does not universally mean “the special bit is ineffective.” [2]
| Special bit | Typical effect | Important distinctions |
|---|---|---|
| SUID | Affects the effective user identity when a supported executable runs | Linux generally does not treat this bit on interpreter scripts as it does on ordinary executables |
| SGID | May affect an executable's effective group identity; on a directory, may make new entries inherit the directory's group | File execution semantics differ from directory inheritance semantics |
| sticky bit | Restricts deletion and renaming in shared directories | Generally, only the file owner, directory owner, or a user with the appropriate privilege can pass this restriction; all other access requirements still apply |
-rwsr-xr-x # 属主 x 位置叠加 SUID
drwxrwxrwt # 目录上设置 sticky,其他用户仍有 xThese two lines only illustrate modes; they are not a recommendation to apply the same settings to arbitrary files. In a shared directory, the rule “everyone can create files, but cannot freely delete other people's files” relies on the combined effects of ordinary directory permissions and the sticky restriction.
Do not interpret all eza characters as if they were ls output#
Listing tools do not display types and extended information in exactly the same way. In eza's file-type rendering, . can represent a regular file and | a FIFO. This dot is not an additional execute-permission bit. Its extended-attribute marker, @, is a different kind of indicator. [5]
ls -l -- example.txt
eza -l -- example.txt
eza -l --extended -- example.txtThis requires eza to be installed. Compare output for the same file and consult the manual for that version when interpreting extended-attribute information. GNU ls itself can also display markers for additional access controls, so do not conclude that “ls always has exactly ten characters.” Colors, icons, and extra columns are only presentation; the final assessment must still come back to file type, owner, group, and access controls. [6]
When you see Permission denied, work through the path#
First identify the denied action: reading, writing, executing, entering a directory, or deleting. Then check the target and its parent directory; for deeper paths, verify search permissions at each level. Next, confirm your current identity and supplementary groups to determine which set of mode bits applies, rather than simply adding the permissions from all three groups together.
id
ls -ld -- project project/docs
ls -l -- project/docs/example.txtIf the mode bits already allow the intended operation, continue checking ACLs, mount state, security policies, and the path the program actually accesses. A symbolic link pointing elsewhere, a program running inside a container, or inspecting a different file from the one named in the error can all create the illusion that “the permissions look fine.” Identifying the precise step being denied is usually faster than recursively opening up the whole directory tree.
References & further reading
- GNU ls manual ↗
- Linux chmod and special mode bits ↗
- Linux path resolution ↗
- Linux unlink permission checks ↗
- eza file-type rendering implementation ↗
- eza manual and extended attributes ↗
Adapted from technical notes. Examples use generic names.