How to Fix Permission Denied in Linux Terminal: A Complete Developer’s Guide
We have all been there. You are cruising through your terminal, setting up a new environment, writing a deployment script, or trying to run a freshly pulled repository, when suddenly, the terminal spits back a cold, frustrating error:
bash: ./deploy.sh: Permission denied
Or perhaps you are trying to edit a configuration file, and your text editor refuses to save, or you get a Permission denied when trying to execute a binary.
If you are currently searching for how to fix permission denied linux terminal, you are in the right place. As developers, we encounter this issue constantly, whether we are working on local Ubuntu virtual machines, configuring cloud EC2 instances, or managing Docker containers.
In this comprehensive guide, we are going to break down exactly why this error happens, how to fix it using step-by-step solutions, and how to configure your system to prevent it from happening again. We will cover standard file permissions, ownership changes, advanced edge cases like SELinux, and common Docker pitfalls.
Let’s dive into the root cause and get your terminal working again.
Understanding the Root Cause: Why Linux Says “No”
Linux is a multi-user operating system built from the ground up with strict security and access controls. Unlike Windows, which often defaults to granting administrative privileges to the primary user, Linux assumes that the user operating the terminal only has access to their own files.
When the terminal returns a “Permission denied” error, it means exactly what it says: the user account executing the command does not have the required rights to interact with the file, directory, or system resource in the way you are asking it to.
The error usually falls into one of these three categories:
1. Execution Rights: You are trying to run a script or binary, but the file is not marked as executable.
2. Read/Write Rights: You are trying to read, modify, or write to a file or directory owned by another user (often the root user) or a different group.
3. System/Security Policies: Advanced security modules like SELinux or AppArmor are blocking access, or you are trying to bind to a restricted system port.
Before we can fix the problem, we need to learn how to read what Linux is telling us.
Step 1: Diagnosing the Problem with ls -l
Before blindly typing commands, let’s diagnose the file or directory causing the issue. The best tool for this is the ls command with the -l (long format) and a (all files) flags.
Run this command in your terminal:
ls -la
You will get an output that looks something like this:
-rw-r--r-- 1 root root 2048 Jan 12 14:32 config.yaml
-rwxr-xr-x 1 devuser devuser 4096 Feb 02 09:15 deploy.sh
drwxr-xr-x 2 devuser devuser 4096 Feb 02 09:15 src
Let’s break down the first column. It consists of 10 characters.
- Character 1: The file type.
-means a standard file.dmeans a directory.lmeans a symbolic link. - Characters 2-4 (Owner): The permissions for the user who owns the file.
rstands for read,wstands for write, andxstands for execute.-means that specific permission is missing. - Characters 5-7 (Group): The permissions for the user group associated with the file.
- Characters 8-10 (Others): The permissions for everyone else on the system.
Looking at our example above, config.yaml is owned by root, and its permissions are -rw-r--r--. This means the root user can read and write to it, but the group and others (which likely includes your current user) can only read it. If you try to write to it, you will get a Permission denied error.
Meanwhile, deploy.sh has the x flag for the owner (-rwxr-xr-x), meaning it can be executed.
Step 2: The Most Common Fix – Adding Execute Permissions
If you downloaded a shell script (.sh), a compiled Go binary, or a Python script with a shebang (#!/usr/bin/env python3), and you get Permission denied when trying to run ./script.sh, the file lacks the execute (x) bit.
By default, Linux strips the execute bit from downloaded files for security reasons. Imagine if a malicious script downloaded automatically and executed itself!
Using chmod to Add Execute Permissions
To fix this, you use the chmod (change mode) command. You can use symbolic notation or octal notation.
Symbolic Notation (Easier to read):
If you want to add execute permissions for the user (owner) of the file, run:
chmod u+x deploy.sh
ustands for user.+means add.xmeans execute.
If you want everyone to be able to execute it, you can use:
chmod +x deploy.sh
Octal Notation (The Developer Standard):
Most developers use numbers to set permissions. This sets the exact permission state rather than modifying a single bit.
chmod 755 deploy.sh
Here is what 755 means:
* 7 (User): Read (4) + Write (2) + Execute (1) = 7. The owner can do everything.
* 5 (Group): Read (4) + Execute (1) = 5. The group can read and run it.
* 5 (Others): Read (4) + Execute (1) = 5. Anyone else can read and run it.
Once you run the chmod command, try executing your file again. 90% of the time, this is the exact fix you are looking for.
Step 3: Fixing Read and Write Permission Denied Errors
Sometimes the error isn’t about running a file, but about modifying it. If your code throws an error trying to write to a log file, or you can’t save changes to a configuration file, you lack write (w) permissions.
Adding Write Permissions
If you own the file but lack write access, you can add it:
chmod u+w config.yaml
Or, using octal notation, to give the owner read/write access while giving everyone else read-only access (standard for config files):
chmod 644 config.yaml
Directory Permissions (The Silent Gotcha)
Many developers do not realize that directory permissions behave differently than file permissions.
If a directory lacks the execute (x) bit, you cannot cd into it, even if you have read permissions. The execute bit on a directory grants the right to traverse the folder structure.
If a directory lacks the read (r) bit, you cannot use ls to list its contents.
If you are getting a Permission denied error when trying to access a folder like /var/log/custom-app/, ensure the directory has execute permissions:
chmod +x /var/log/custom-app/
Step 4: Changing File Ownership with chown
Often, Permission denied errors happen because you are simply not the owner of the file. For example, if you ran a Docker container that created files on your host machine, those files are likely owned by the root user. If you try to delete them as a standard user, Linux will block you.
To check who owns the file, look at the 3rd and 4th columns of the ls -l output.
If you need to take ownership of a file or directory, use the chown (change owner) command.
Changing a single file:
sudo chown devuser:devuser config.yaml
Format: sudo chown [user]:[group] [filename]
Changing a directory and all its contents recursively:
If an entire project folder was created by root, you will want to use the -R (recursive) flag.
sudo chown -R devuser:devuser /home/devuser/project-folder
Once you own the file, you will no longer need sudo to edit it, and the Permission denied errors will disappear.
Step 5: Using Sudo Privileges Safely
Sometimes, a file is supposed to be owned by root, and you have no business changing its ownership. Think of system files like /etc/hosts, package manager caches, or web server configurations in /etc/nginx/.
If you need to modify these files, you must temporarily elevate your privileges using sudo (Super User DO).
sudo nano /etc/nginx/nginx.conf
When to use sudo
- Editing files in
/etc/,/var/, or/opt/. - Installing packages via
aptoryum. - Restarting system services like
systemctl restart nginx.
A crucial warning for developers: Do not fall into the trap of using sudo to run your application code just to bypass permission errors. For example, running sudo npm start or sudo python app.py is a terrible practice. It masks underlying permission issues, causes new files to be generated as root (which you won’t be able to edit later without sudo), and creates massive security vulnerabilities. Always fix the underlying file permissions instead of forcing it with sudo.
Advanced Edge Cases and Developer Environments
If you have tried chmod and chown and you are still getting a permission denied error, you have hit an edge case. As a modern developer, you are likely working with containers, restricted ports, or advanced security modules. Let’s troubleshoot the complex scenarios.
Edge Case 1: Restricted Network Ports (EACCES)
If you are building a web server using Node.js, Python, or Go, and you try to run it on port 80 or