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

Sponsored

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 sudo sometimes 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 file
  • rw- → owner (user) can read and write
  • r-- → group can only read
  • r-- → 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.sh adds execute for the user.
  • Octal: chmod 750 /var/www sets 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 077 on 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 pipefail in 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 777 for "quick fixes" — it grants full rights to everyone, a common security hole.
  • Changing permissions on a symlink accidentally — chmod follows symlinks by default.
  • Ignoring umask and wondering why new files aren't as restrictive as expected.

Variations

  1. Use setfacl for granular per-user or per-group permissions when the standard model is too coarse.
  2. On some systems, the chattr command can set immutable flags for extra protection against accidental changes.
  3. 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.
  • chown changes owner/group; you need root to change the owner.
  • umask sets default permissions for new files — always set it to a secure value.
  • Always verify with ls -l after changing permissions.

Sponsored

Sponsored

Discussion

Questions, corrections, and tips help everyone reading this page.

0 comments

Add a comment

Shown publicly with your comment.

Be constructive · max 4,000 characters

No comments yet — start the thread.

Related tutorials, quizzes, and articles for this topic.