Manage Files and Permissions
Manage files and permissions in Linux — chmod, chown, umask. Hands-on exercise, troubleshooting, and next steps in the Linux · networking · telemetry track.
Focus: manage files and permissions
Imagine you've just deployed a service to a Linux server, only to find the process crashes instantly with a cryptic error like Permission denied or Operation not permitted. Or you've run a script and been locked out of a directory you created yourself. These frustations are almost always caused by a misunderstanding of how Linux manages files and permissions. In this lesson, you'll stop fighting the system and start controlling it, learning how to read, interpret, and set permissions with precision. By the end, you'll be able to diagnose access issues in seconds and design secure, predictable file layouts for any deployment.
The problem this lesson solves
When you're working across a fleet of Linux servers, file permissions are the invisible gatekeepers that decide who can read, write, or run what. Problems arise when you can't predict or control those gates. Have you ever had to:
- Give a web server access to a directory without exposing sensitive files?
- Allow a CI/CD agent to create logs but not delete the application binary?
- Understand why
sudosometimes isn't the right fix?
If any of those sound familiar, this lesson is for you. Misconfigured permissions lead to security holes (world-readable secrets), downtime (services that can't write their state), and painful debugging sessions. Once you understand the system, you'll stop guessing and start managing files and permissions with confidence.
Core concept / mental model
Think of every file and directory as a document with a lockbox containing three sets of keys, each with three positions. The sets correspond to user (the file's owner), group (a shared group of users), and other (everyone else). The positions are read, write, and execute.
For a file:
- Read — you can view the contents (e.g.,
cat) - Write — you can modify the contents
- Execute — you can run it as a command/script
For a directory, the meanings shift:
- Read — you can list the names inside
- Write — you can create or delete files inside
- Execute — you can traverse into the directory and access files within
You can imagine a directory as a busy train station: read lets you see the departure board, execute lets you walk onto the platforms, and write lets you add or remove trains. Without execute on a directory, even with read, you can't actually reach the files inside. This is a classic trap.
Every file also has an owner and a group, plus a set of metadata like timestamps. The commands that manage all of this are chmod (change mode), chown (change owner), and umask (set default permissions for new files).
A quick mental model: chmod controls the lockbox keys, chown decides who holds the lockbox, and umask sets the default factory settings.
How it works step by step
1. Read the current permissions
Start with ls -l to see a detailed listing. The first column shows the type (e.g., - for file, d for directory) followed by ten characters that encode the permissions.
$ ls -l /var/log/app.log
-rw-r--r-- 1 deploy devops 2048 Mar 12 10:00 app.log
Decoding -rw-r--r--:
-→ regular filerw-→ owner (user) can read and writer--→ group can only readr--→ others can only read
If you ever need a numeric shorthand, each permission has a value: read=4, write=2, execute=1. Add them up for each set. So rwx = 7, rw- = 6, r-- = 4. The above file is 644.
2. Change permissions with chmod
You can use symbolic mode (letters) or octal mode (numbers).
- Symbolic:
chmod u+x script.shadds execute for the user. - Octal:
chmod 750 /var/wwwsets owner full, group read+execute, others nothing.
Use octal when you want to set a precise state, and symbolic when you only need to tweak one flag.
3. Change owner and group with chown
chown lets you transfer ownership. You need root privileges to change the owner, but a group owner can sometimes be changed by the current owner if they belong to that group.
sudo chown deploy:devops /var/www/html
This sets the owner to deploy and the group to devops. Use the -R flag to apply recursively — but be careful with directories that contain symlinks.
4. Set default permissions with umask
umask is a shell built-in that masks out permissions when a new file or directory is created. The default file permissions are 666 (rw-rw-rw-) and directories 777 (rwxrwxrwx). The umask subtracts from those.
A umask 022 means new files get 644 (rw-r--r--) and directories get 755 (rwxr-xr-x). A more secure umask 077 gives 600 for files and 700 for directories — everything private by default.
Pro tip: Always set
umask 077on servers that handle customer data. It's a low-effort security win.
5. Test with test or ls -l
After any change, verify with ls -l or use the test command in scripts to avoid brittle assumptions.
Hands-on walkthrough
Let's build a small project directory with a script, a data file, and a log folder, then set permissions the way a real service would need.
Set up the workspace
mkdir -p ~/project/{scripts,data,logs}
touch ~/project/scripts/deploy.sh
chmod 754 ~/project/scripts/deploy.sh
ls -l ~/project/scripts/
Expected output:
-rwxr-xr-- 1 you yourgroup 0 ... deploy.sh
The owner can read/write/execute, group can read/execute, others can only read.
Change ownership
Suppose your service runs as user app in group appgrp:
sudo chown -R app:appgrp ~/project/data
dir
Check the change:
ls -ld ~/project/data
Output should show app:appgrp.
Default permissions with umask
Run a subshell to test a new file's default permissions:
(umask 077 && touch ~/project/data/secret.txt && ls -l ~/project/data/secret.txt)
Output:
-rw------- 1 you yourgroup 0 ... secret.txt
Full exercise
Write a small bash script that checks and fixes permissions:
#!/bin/bash
# fix_perms.sh
DIR=${1:-~/project}
chmod 755 "$DIR"
chmod 700 "$DIR/scripts"
chown -R deploy:devops "$DIR" # needs sudo if not owner
echo "Permissions fixed for $DIR"
Run it with bash fix_perms.sh ~/project and observe the changes.
Pro tip: Always use
set -euo pipefailin scripts like this to fail fast on permission errors.
Compare options / when to choose what
| Approach | When to use | Pros | Cons |
|---|---|---|---|
Octal (chmod 750) |
Setting exact final state | Precise, predictable, easy to read in docs | Harder to remember instantly |
Symbolic (chmod u+x) |
Small tweaks, quick fixes | Simple, intuitive | Can accumulate unintentional permissions over time |
ACLs (setfacl) |
Complex multi-user scenarios | Granular per-user or per-group control | Extra complexity, less portable |
| umask | Default policy for new files | Automatic security baseline | Not a replacement for explicit chmod |
For most deployments, start with octal and umask. Use ACLs sparingly — they add mental overhead and can break configuration management tools.
Troubleshooting & edge cases
1. "Permission denied" when you are the owner
Check the directory's execute bit. If dr--r--r-- on a directory, you can list it but not traverse. Add chmod u+x dir to allow access.
2. chown fails with "Operation not permitted"
You likely need sudo. The current user must be root or the new owner must be the same as the current owner.
3. chmod on symlinks is ignored
chmod on a symlink changes the target, not the link. Use chmod -h to change the link itself (rarely needed).
4. Scripts get "Permission denied" even with sudo bash script.sh
That's expected because bash reads the file as the invoking user. Use chmod u+x script.sh and run ./script.sh instead.
5. Files created with unexpected permissions
Check your umask. Many distros default to 022 (files 644), but if you're in a hardened environment, it might be 077.
6. ACLs complicate everything
If you see a + in ls -l (e.g., -rw-r--r--+), there is an ACL. Use getfacl to inspect and setfacl -b to remove all ACLs before making standard chmod changes.
What you learned & what's next
You've now mastered the core idea behind managing files and permissions: reading the three-tier read/write/execute system, applying changes with chmod and chown, and setting sane defaults with umask. You completed a hands-on exercise that combined these tools in a realistic project layout, and you learned to troubleshoot common edge cases like directory traversal failures and symlink quirks.
These skills are the foundation for the next lesson in the Linux · networking · telemetry track: managing systemd services. When you define a unit file, you'll need to specify the User=, Group=, and file paths — and you'll immediately understand why your service can or cannot read its config files. Permissions are the silent partner in every process you run.
Go ahead and create a sandbox directory, set strict umask 077, and try to read a file as another user. The more you poke at it, the more natural it becomes.
Practice recap
Create a test_perms directory, add a few files, and set permissions so only you can read them (700 for files). Then try to access them as another user (e.g., su nobody -s /bin/bash). Notice the difference between read and execute. Finally, change the umask to 077 and create a new file to see how defaults change.
Common mistakes
- Forgetting the execute bit on a directory — you can list it, but not access files inside.
- Using
chmod 777for "quick fixes" — it grants full rights to everyone, a common security hole. - Changing permissions on a symlink accidentally —
chmodfollows symlinks by default. - Ignoring umask and wondering why new files aren't as restrictive as expected.
Variations
- Use
setfaclfor granular per-user or per-group permissions when the standard model is too coarse. - On some systems, the
chattrcommand can set immutable flags for extra protection against accidental changes. - If you're in a container or orchestration environment, define file permissions in your image build instead of at runtime for consistency.
Real-world use cases
- Securing a web server's document root:
chown -R www-data:www-data /var/www/html && chmod 750 /var/www. - Allowing a CI/CD runner to write logs while keeping the source code read-only.
- Creating a shared data directory for a team where everyone can read/write but only the owner can delete files.
Key takeaways
- File permissions are defined for user, group, and other, with read/write/execute flags each.
- Directory execute permission is required to access files inside, not just read.
- Use octal notation (like 750) for precise, repeatable permission settings.
chownchanges owner/group; you need root to change the owner.umasksets default permissions for new files — always set it to a secure value.- Always verify with
ls -lafter changing permissions.
Keep learning
Related tutorials, quizzes, and articles for this topic.
Discussion
Questions, corrections, and tips help everyone reading this page.
0 comments
Add a comment
No comments yet — start the thread.