Overview
The Filesystem Hierarchy Standard defines where files belong on a Unix-like system, /etc for host-specific configuration, /var for logs and other data that grows continuously, /usr for installed, largely read-only programs and libraries, /opt for add-on software packages, so that the same paths mean the same thing across distributions and tools can rely on it. On top of that structure, every file and directory carries a permission mode, three octal digits for owner/group/other read-write-execute bits, plus an optional fourth digit for setuid, setgid, and the sticky bit, and every newly created file's actual permissions are the requested mode with the current umask's bits turned off, unless a default ACL on the parent directory overrides that entirely.
Quick Reference
| Directory | Purpose |
|---|---|
/etc | Host-specific configuration |
/var | Logs, caches, and other continuously-changing data |
/usr | Installed programs, libraries, and documentation |
/opt | Add-on application software packages |
/home | User home directories |
| Permission bit | Value | Meaning on a file | Meaning on a directory |
|---|---|---|---|
| read (r) | 4 | View contents | List entries |
| write (w) | 2 | Modify contents | Create/remove entries |
| execute (x) | 1 | Run as a program | Traverse (cd into it) |
Syntax
chmod 755 deploy.sh # rwxr-xr-x - owner full, group/others read+execute
chmod 644 config.yaml # rw-r--r-- - owner read+write, group/others read-only
chown deploy:deploy app/ # change owner and groupExamples
# umask 022 turns off write for group/others on every new file -
# a requested 0666 becomes 0644, a requested 0777 becomes 0755.
umask 022
touch newfile # ends up 0644, not 0666setgid on a shared directory keeps group ownership consistent
Setting the setgid bit on a directory (chmod 2775 shared/) makes every new file created inside inherit the directory's group, instead of the creating user's primary group, which is what actually keeps a shared team directory's group ownership consistent over time.
Visual Diagram
Common Mistakes
- Assuming a requested mode like
0666in application code is the permission a new file will actually get, without accounting for the process's umask. - Using
chmod -R 777to "fix" a permissions problem, which removes all access control rather than granting the specific access actually needed. - Storing application configuration outside
/etcor mutable data outside/var, breaking the assumption other tools (backup scripts, package managers) rely on. - Forgetting that a default ACL on a parent directory overrides the umask entirely, then being confused when new files don't have the permissions the umask alone would predict.
Performance
- Filesystem hierarchy placement is a management/organizational concern, not a runtime performance one; the practical performance angle is mounting
/varor/tmpon separate, appropriately-fast storage when I/O patterns justify it. - Permission checks (the read/write/execute bits, plus ACLs if present) are evaluated by the kernel on every file access but are computationally negligible compared to the I/O itself.
Best Practices
- Follow the FHS placement conventions (
/etcfor config,/varfor variable data,/optfor add-on packages) so other tools and administrators can find things predictably. - Set an explicit, deliberate umask (commonly
022or027) rather than relying on whatever a shell or service happens to default to. - Grant the minimum permission bits actually needed; reach for a specific
chmod, not a blanket777. - Use setgid on shared team directories so new files consistently inherit the right group, instead of manually fixing group ownership after the fact.