You just tried to run a script or edit a config file, and the terminal spat back: Permission denied. Frustrating, right? This guide will show you exactly how to change file permissions Linux to fix that error and take full control of your system.
I've spent the better part of fifteen years working with Linux systems—from small Raspberry Pi projects to production servers handling millions of requests. And I can tell you this: file permissions are one of those things that seem confusing at first, but once you understand the underlying model, everything clicks into place. It's like learning to read a map. At first, all those symbols look like noise. Then suddenly, you see the terrain.
We'll cover the permission model from the ground up, walk through chmod in both symbolic and numeric modes, tackle real-world examples, and dig into troubleshooting those dreaded Permission denied errors. By the end, you'll be modifying file ownership and permissions with confidence.
Understanding Linux File Permissions: Users, Groups, and Read Write Execute
Before we start changing anything, we need to understand what we're actually looking at. Linux file permission octal notation isn't just a random string of characters—it's a carefully designed system that keeps multi-user environments secure.
Think of it like an apartment building. The building has common areas, individual units, and a management office. Not everyone gets a key to everything. The same logic applies to files on a Linux system.
The Three User Classes: User, Group, and Other
Every file on a Linux system has an owner—a user who created it or was assigned ownership. That's the user class (u). But files also belong to a group (g), which is a collection of users who share access. Everyone else on the system falls into the others class (o).
Here's the critical part: these three classes are mutually exclusive. When the system checks your access to a file, it runs through a simple logic:
- Are you the file owner? If yes, you get the owner's permissions. Done.
- If not, are you a member of the group that owns the file? If yes, you get the group's permissions. Done.
- If neither, you fall into "others" and get those permissions.
-rw-r--r-- 1 john developers 2048 Jan 12 10:30 report.txt
─┬─ ──┬── ─┬─ ───┬───
│ │ │ └── group owner (developers)
│ │ └── user owner (john)
│ └── permission string (user/group/others)
└── file type (- = regular file, d = directory)
I've seen countless situations where someone is confused why they can't access a file even though they're in the right group. Nine times out of ten, it's because the file's group owner isn't set to the group they think it is. The ls -l output doesn't lie—check it first.
Decoding Permission Types: Read, Write, and Execute
Now let's talk about what those r, w, and x characters actually mean. The read (r) permission lets you view a file's contents. Write (w) lets you modify it. Execute (x) lets you run it as a program or script.
But here's where it gets interesting: these permissions behave differently for directories.
| Permission | File | Directory |
|---|---|---|
| Read (r) | View file contents | List files in the directory (e.g., ls) |
| Write (w) | Modify file contents | Create, delete, or rename files within the directory |
| Execute (x) | Run the file as a program | Access the directory (e.g., cd into it) and access file metadata |
| That last one trips up a lot of beginners. You can have read permission on a directory, but without execute permission, you can't actually get into it. It's like being able to see the menu outside a restaurant but never being allowed through the door. |
Common combinations you'll see:
rw-— read and write, no execute (typical for data files)r-x— read and execute, no write (typical for system binaries)rwx— full access (typical for directories and scripts you own)
How to View Permissions with ls -l
The ls -l command is your window into the permission system. Let's break down what you're seeing:
$ ls -l
drwxr-xr-x 2 root root 4096 Jun 13 20:25 tuned
-rw-r--r-- 1 root root 4017 Feb 24 2022 vimrc
The first character tells you the file type: - for a regular file, d for a directory, l for a symbolic link. The next nine characters are the permission string, split into three groups of three: user, group, and others.
So -rw-r--r-- breaks down as:
- File type:
-(regular file) - User permissions:
rw-(read and write) - Group permissions:
r--(read only) - Others permissions:
r--(read only)
The dot after the permission string (e.g., rw-r--r--.) indicates SELinux context is present, which we'll touch on later in the troubleshooting section.
Mastering chmod: Symbolic Mode vs. Numeric Mode (Octal Notation)
Now we get to the good stuff. The chmod command—short for "change mode"—is how you modify permissions. There are two ways to use it: symbolic mode and numeric mode. Both accomplish the same thing, but they feel different in practice.
I'll be honest: I use numeric mode 90% of the time because it's more precise and easier to script. But symbolic mode is invaluable when you just want to make a quick tweak without calculating values.
Using Symbolic Mode: Adding and Removing Permissions
Symbolic mode uses letters to represent user classes and permissions, with operators to add, remove, or set permissions.
The syntax is: chmod [ugoa][+-=][rwx] file
| Operator | Function | Example |
|---|---|---|
+ | Adds a permission | chmod u+x script.sh — adds execute for the user |
- | Removes a permission | chmod go-w file.txt — removes write for group and others |
= | Sets exact permissions | chmod u=rwx file.txt — sets user to read/write/execute |
| You can combine multiple operations with commas: |
$ chmod u+x,go-w script.sh
This adds execute for the user and removes write for group and others in one command. The a class (all) is shorthand for ugo:
$ chmod a+x script.sh # same as chmod ugo+x script.sh
One thing I've learned the hard way: chmod +x without specifying a class applies to all classes. That's usually fine for making a script executable, but be aware it's granting execute to everyone, not just you.
Using Numeric Mode: The Power of Octal Values
Numeric mode—also called octal notation—represents permissions as numbers. Each permission has a value:
- Read (
r) = 4 - Write (
w) = 2 - Execute (
x) = 1
You add these values together for each user class, then string the three digits together. So 755 means:
- User: 7 = 4+2+1 =
rwx - Group: 5 = 4+0+1 =
r-x - Others: 5 = 4+0+1 =
r-x
Here's a quick reference table I keep handy:
| Value | Symbolic | Meaning | Typical Use |
|---|---|---|---|
| 644 | rw-r--r-- | Owner can read/write, others can read | Regular files, config files |
| 755 | rwxr-xr-x | Owner can do everything, others can read/execute | Directories, executables, scripts |
| 700 | rwx------ | Only owner can access | Private scripts, personal directories |
| 600 | rw------- | Only owner can read/write | SSH private keys, sensitive data |
| 664 | rw-rw-r-- | Owner and group can read/write, others read | Collaborative files |
| 777 | rwxrwxrwx | Everyone can do everything | Avoid unless absolutely necessary |
The calculation is straightforward once you get the hang of it. For example, to set rwxr-x---: |
- User: rwx = 4+2+1 = 7
- Group: r-x = 4+0+1 = 5
- Others: --- = 0+0+0 = 0
Result: chmod 750 file.txt
chmod 755 vs 644: What's the Difference and When to Use Each
This is probably the most common question I get from developers. Let's settle it once and for all.
| chmod 755 | chmod 644 | |
|---|---|---|
| Symbolic | rwxr-xr-x | rw-r--r-- |
| Owner | Read, write, execute | Read, write |
| Group | Read, execute | Read |
| Others | Read, execute | Read |
| Best for | Directories, scripts, executables | Regular files, documents, configs |
The rule of thumb: directories need execute permission so users can cd into them. Files generally don't need execute unless they're programs or scripts. |
I recommend 755 for directories and 644 for regular files as your default starting point. It's secure enough for most use cases while still being functional. And please—for the love of all that is holy—avoid 777 unless you have a very specific reason. I've seen too many security breaches start with someone running chmod -R 777 /var/www to "fix" a permissions issue.
Practical Examples: Changing Permissions for Files and Directories
Theory is great, but let's get our hands dirty with real examples. These are the commands I actually use in my day-to-day work.
How to Make a File Executable with chmod +x
You've written a Bash script and you're ready to run it. But when you try ./myscript.sh, you get Permission denied. Here's the fix:
$ ls -l myscript.sh
-rw-r--r-- 1 john john 256 Jan 15 14:22 myscript.sh
$ chmod +x myscript.sh
$ ls -l myscript.sh
-rwxr-xr-x 1 john john 256 Jan 15 14:22 myscript.sh
$ ./myscript.sh
Hello, world!
The difference between chmod +x and chmod 755? chmod +x only adds execute permission to whatever's already there—it doesn't touch read or write. chmod 755 sets everything explicitly. In most cases, chmod +x is sufficient and safer because it preserves your existing read/write settings.
Recursively Change File Permissions with -R
When you need to change permissions on a directory and everything inside it, the -R flag is your friend:
$ chmod -R 755 /var/www/html
This sets 755 on the directory and all files and subdirectories within. But here's a word of caution: this is a blunt instrument. If you have files that should be 644 (like PHP scripts that don't need execute) and directories that should be 755, a blanket chmod -R 755 will make everything executable. That's not ideal from a security perspective.
A better approach is to use find to target specific file types:
$ find /var/www/html -type f -exec chmod 644 {} \;
$ find /var/www/html -type d -exec chmod 755 {} \;
This sets files to 644 and directories to 755, which is the correct setup for most web servers.
Changing File Owner and Group with chown and chgrp
chmod changes permissions, but chown changes ownership. These are two different things, and confusing them is a common mistake.
$ sudo chown john:developers report.txt
This sets the user owner to john and the group owner to developers. You can change just the user or just the group:
$ sudo chown john report.txt # change user only
$ sudo chown :developers report.txt # change group only
The chgrp command does the same thing as chown :group:
$ sudo chgrp developers report.txt
You'll need sudo for most chown operations because changing ownership is a privileged action. And here's a tip: when you're setting up shared directories for a team, make sure the group ownership is correct and that the directory has the right group permissions. I've seen too many collaborative projects grind to a halt because someone created files with their personal group instead of the team group.
Troubleshooting: How to Fix Permission Denied Errors in Linux
The Permission denied error is the bane of every Linux user's existence. Let's systematically work through the most common causes and fixes.
Common Causes of 'Permission Denied'
Here's my diagnostic checklist when someone comes to me with a permission issue:
- Wrong ownership: The file is owned by another user. Check with
ls -l. - Missing execute on a directory: You can't traverse a directory without execute permission. This is huge—even if you have read access to a file, you need execute on every directory in its path.
- Read-only filesystem: The filesystem itself is mounted read-only. Check with
mount | grep ro. - Immutable attribute: The file has the immutable attribute set. Check with
lsattr.
Let's walk through a real scenario:
$ cat /etc/nginx/sites-available/mysite.conf
cat: /etc/nginx/sites-available/mysite.conf: Permission denied
$ ls -l /etc/nginx/sites-available/mysite.conf
-rw-r----- 1 root www-data 2048 Jan 12 10:30 mysite.conf
$ id
uid=1000(john) gid=1000(john) groups=1000(john),27(sudo)
The file is owned by root:www-data. I'm john, and I'm not in the www-data group. The "others" permissions are ---, so I have no access. The fix? Either add myself to the www-data group or use sudo to read the file.
Why You Get 'Permission Denied' Even with 777 Permissions
This is the one that really confuses people. You've set 777 on everything and you still can't access the file. What gives?
The answer is usually one of two things: SELinux or AppArmor. These are mandatory access control (MAC) systems that work alongside traditional permissions. Even if traditional permissions say "everyone can access this," SELinux can override that.
I remember debugging a web server issue where the logs showed Permission denied even though the files were 777. After hours of head-scratching, I ran:
$ ls -Z /var/www/html/index.html
-rw-r--r--. root root system_u:object_r:httpd_sys_content_t:s0 /var/www/html/index.html
The SELinux context was wrong. The fix was:
$ sudo restorecon -Rv /var/www/html
If you're on a system with SELinux (like RHEL, CentOS, or Fedora), check the context with ls -Z. If you're on Ubuntu or Debian, it's likely AppArmor, and the troubleshooting path is different.
Using sudo to Overcome Permission Issues
When you need to change permissions on files you don't own, sudo is your tool:
$ sudo chown root:root /etc/nginx/nginx.conf
$ sudo chmod 644 /etc/nginx/nginx.conf
But here's my advice: use sudo sparingly. Every time you use it, you're operating outside your normal permissions, which increases the risk of mistakes. I've seen sysadmins accidentally chmod -R 777 / because they were in a hurry with sudo. Always double-check your command before hitting Enter.
Advanced Permissions: Special Bits, umask, and Best Practices
Once you've mastered the basics, it's time to explore the deeper waters of Linux permissions.
Special Permissions: setuid, setgid, and Sticky Bit
Beyond the standard rwx permissions, Linux has three special permission bits that add extra functionality:
| Special Bit | Numeric Value | Effect |
|---|---|---|
| setuid (SUID) | 4 | When set on an executable, it runs with the file owner's privileges, not the user who launched it |
| setgid (SGID) | 2 | On executables, runs with the group's privileges. On directories, new files inherit the directory's group |
| Sticky bit | 1 | On directories, only the file owner (or root) can delete files, even if others have write access |
You've probably used SUID without realizing it. The passwd command is a classic example: |
$ ls -l /usr/bin/passwd
-rwsr-xr-x 1 root root 68208 Nov 15 2023 /usr/bin/passwd
See the s in the user permissions? That's SUID. It allows any user to change their password, even though the command needs root privileges to modify /etc/shadow.
The sticky bit is most commonly seen on /tmp:
$ ls -ld /tmp
drwxrwxrwt 20 root root 4096 Jan 15 14:30 /tmp
The t at the end means only the file owner can delete their own files, even though everyone has write access.
You can set these with chmod:
$ chmod 4755 script.sh # setuid
$ chmod 2755 directory/ # setgid
$ chmod 1777 /tmp # sticky bit
Understanding umask: Setting Default Permissions for New Files
Ever wonder why new files are created with 644 permissions instead of 666? That's umask at work. It's a mask that removes permissions from the default values.
The default permissions are 666 for files and 777 for directories. The umask subtracts from these:
| umask | File permissions | Directory permissions |
|---|---|---|
| 022 | 644 (rw-r--r--) | 755 (rwxr-xr-x) |
| 002 | 664 (rw-rw-r--) | 775 (rwxrwxr-x) |
| 077 | 600 (rw-------) | 700 (rwx------) |
| To view your current umask: |
$ umask
0022
To change it:
$ umask 077
This is particularly important for security-sensitive environments. If you're working with sensitive data, a umask of 077 ensures new files aren't accidentally world-readable.
Security Best Practices for Managing File Permissions
After years of managing Linux systems, here are the practices I've found most valuable:
- Follow the principle of least privilege: Grant only the permissions necessary for the task. If a user needs to read a file, don't give them write access.
- Avoid 777 like the plague: There's almost always a better solution. Use 755 for directories, 644 for files.
- Audit regularly: Use
findto spot problematic permissions:
$ find / -perm -002 -type f 2>/dev/null # world-writable files
$ find / -perm -4000 -type f 2>/dev/null # setuid files
- Use groups effectively: Instead of giving individual users access to files, create groups and assign permissions at the group level. It's much easier to manage.
Frequently Asked Questions
How do I give chmod 777 to a file?
The command is chmod 777 filename. This grants read, write, and execute permissions to everyone—the owner, group, and all other users. While this will certainly fix any permission issues, I strongly advise against using it in production. It means anyone on the system can modify or execute the file, which is a significant security risk. Consider chmod 755 (owner has full access, others can read/execute) or chmod 750 (owner has full access, group can read/execute, others have no access) as safer alternatives.
What does chmod 444 mean?
chmod 444 sets permissions to r--r--r--, meaning everyone can read the file, but no one can write to it or execute it. This is useful for configuration files that should be visible but not modified, or for documents that need to be shared read-only. Just remember: if you need to edit the file later, you'll need to change the permissions back.
What does chmod 600 and 700 do?
chmod 600 (rw-------) gives the owner read and write access, with no permissions for anyone else. This is the standard for SSH private keys—they should never be accessible by other users. chmod 700 (rwx------) adds execute permission for the owner, making it suitable for personal scripts or directories that only you should access.
What is the difference between chmod and chown?
chmod changes the permission bits on a file—who can read, write, and execute it. chown changes the ownership—which user and group own the file. They work together: chown determines who the permissions apply to, and chmod determines what those permissions are. For example, chown john:developers file.txt makes John the owner and the developers group the group owner, then chmod 750 file.txt gives John full access, the group read/execute, and everyone else nothing.
Wrapping Up
We've covered a lot of ground here. From understanding the three user classes and the read/write/execute permissions, to mastering chmod in both symbolic and numeric modes, to troubleshooting those frustrating Permission denied errors.
The key takeaways:
- Permissions are about control: They determine who can do what with your files and directories.
chmodchanges permissions,chownchanges ownership: Don't confuse the two.- Least privilege is your friend: Grant only what's necessary, and avoid 777.
- Troubleshooting is systematic: Check ownership, check permissions, check for SELinux/AppArmor.
The best way to learn is to practice. Open a terminal, create some test files, and experiment with different permission combinations. Break things, fix them, and break them again. That's how you'll truly internalize how Linux file permissions work.
And if you're looking for a handy reference, download our free Linux permissions cheat sheet (PDF) with all the commands and tables from this guide, and subscribe to our newsletter for more Linux tips and tutorials.





