What are File Permissions and How Do I Change Them?
Read, write, execute — who can do what with your files, and why Unix cares
After this lesson, you will be able to:
- Read and interpret the 10-character permission string (e.g.,
rwxr-xr--) - Convert between symbolic (
rwxr-x---) and octal (750) permission notation - Change permissions with
chmodusing both symbolic (u+x) and octal (644) modes - Explain the meaning of read, write, and execute for both files and directories
- Identify common permission patterns (
644for files,755for executables,700for private)
Why Does My Script Say “Permission Denied”?
You’ve written a shell script, you try to run it with ./myscript.sh, and you get:
bash: ./myscript.sh: Permission denied
The file is right there. You can cat it. You can read every line. But you can’t run it. What’s going on?
The answer is Unix’s permission system — a security model designed in the 1970s when multiple people shared the same physical computer. It controls who can read, write, and execute every file on the system. And even though you might be the only user on your VM, permissions still matter: they affect how your programs run, how your labs get graded, and how real-world servers stay secure.
./myscript.sh, but get "Permission denied." The file exists and you can read it with cat. What's the most likely fix?x) permission. chmod +x adds execute permission. You can read the file (cat works) because you have read permission — but running it as a program requires execute permission. Using sudo would work but is overkill and a bad habit.
Understanding and Changing Permissions
The Permission Model
Every file in Unix has three pieces of ownership information:
- Owner (user) — the person who created the file
- Group — a set of users who share access
- Other — everyone else on the system
And for each of these three categories, there are three permissions:
| Permission | Letter | On Files | On Directories |
|---|---|---|---|
| Read | r |
View contents | List contents with ls |
| Write | w |
Modify contents | Create/delete files inside |
| Execute | x |
Run as program | Enter with cd |
That’s 3 categories × 3 permissions = 9 permission bits per file.
Reading ls -l Output
Let’s create a file and look at its permissions:
touch testfile.txt
ls -l testfile.txt
-rw-r--r-- 1 student student 0 Apr 7 09:15 testfile.txt
Breaking down -rw-r--r--:
- rw- r-- r--
│ │ │ │
│ │ │ └── Other: read only
│ │ └── Group: read only
│ └── Owner: read and write
└── File type: - = regular file, d = directory
Key Insight: “Other” does NOT mean “no one.” It means “every user on the system who isn’t the owner and isn’t in the file’s group.” On a shared server, that could be hundreds of people.
Changing Permissions with chmod
chmod (change mode) has two notations. Let’s learn both.
Symbolic notation — human-readable:
chmod u+x myscript.sh # Add execute for owner (user)
chmod g-w myfile.txt # Remove write for group
chmod o= secret.txt # Remove all permissions for other
chmod a+r readme.txt # Add read for all (a = everyone)
chmod u=rwx,g=rx,o=r myfile # Set exactly
The pattern is: who (u/g/o/a) + operator (+/-/=) + what (r/w/x).
Octal notation — compact and precise:
Each permission has a numeric value:
r (read) = 4
w (write) = 2
x (execute) = 1
Add them up for each category:
| Octal | Binary | Permission |
|---|---|---|
| 7 | 111 | rwx (4+2+1) |
| 6 | 110 | rw- (4+2+0) |
| 5 | 101 | r-x (4+0+1) |
| 4 | 100 | r-- (4+0+0) |
| 0 | 000 | --- (0+0+0) |
So chmod 755 myfile means:
- Owner: 7 =
rwx - Group: 5 =
r-x - Other: 5 =
r-x - Result:
rwxr-xr-x
Key Insight: Octal is just binary in disguise.
rwx=111binary =7octal.r-x=101binary =5octal. Once you see the pattern, converting becomes instant. Think of eachrwxtriplet as a 3-bit binary number.
chmod 641 produce?rw- (4+2), 4 = r-- (4+0+0), 1 = --x (0+0+1). Result: rw-r----x. If you picked A, that's 661. If you picked D (rw-r--r--), that's 644 — you misread the last digit. Decompose each octal digit into its binary bits: 4=read, 2=write, 1=execute.
Why does this matter?
When your compiled C program won’t run and says “Permission denied,” it’s almost always a missing execute bit. When your program can’t read an input file, it’s a missing read bit. Octal notation shows up in Makefile targets, deployment scripts, and stat output — you’ll read these numbers all quarter.
Common Permission Patterns
You’ll use these constantly:
| Octal | String | Use Case |
|---|---|---|
755 |
rwxr-xr-x |
Executable programs, public directories |
644 |
rw-r--r-- |
Source code, text files, configs |
700 |
rwx------ |
Private directory (only you) |
600 |
rw------- |
Private file (only you) |
775 |
rwxrwxr-x |
Shared group directory |
664 |
rw-rw-r-- |
Shared group file (Ubuntu default for new files) |
Let’s Break Things (Safely)
The best way to understand permissions is to experiment. Let’s create a test environment:
mkdir ~/perm-test
cd ~/perm-test
echo "Hello from testfile" > testfile.txt
mkdir testdir
echo "Inside the directory" > testdir/inner.txt
Experiment 1: Remove read from a file
chmod u-r testfile.txt
cat testfile.txt # Permission denied!
chmod u+r testfile.txt # Fix it
Experiment 2: Remove execute from a directory
chmod u-x testdir
cd testdir # Permission denied!
ls testdir # Might show names but no details
cat testdir/inner.txt # Permission denied!
chmod u+x testdir # Fix it
The Trick: For directories,
xmeans “traverse” or “search.” Withoutx, you can’tcdinto the directory and you can’t access anything inside it by name — even if you know the filename. A directory withrbut noxshows you names but won’t let you access them. A directory withxbut norlets you access files by name but won’t let you list them.
Experiment 3: Remove write from a directory
chmod u-w testdir
touch testdir/newfile.txt # Permission denied!
rm testdir/inner.txt # Permission denied!
echo "append" >> testdir/inner.txt # This WORKS! (file write, not dir write)
chmod u+w testdir # Fix it
Common Pitfall: Deleting a file is a directory operation, not a file operation. You need write permission on the directory to delete a file inside it — the file’s own permissions don’t matter for deletion. This surprises everyone the first time.
r-x for the owner. The owner tries to create a new file inside it with touch newfile.txt. What happens?w bit controls whether you can add or remove entries. The r bit lets you list contents, and the x bit lets you traverse into it. You need w specifically to modify what's in the directory.
Solving the “Permission Denied” Mystery
Now back to our opening question. Why couldn’t we run ./myscript.sh?
echo '#!/bin/bash' > myscript.sh
echo 'echo "Hello from script!"' >> myscript.sh
ls -l myscript.sh
-rw-r--r-- 1 student student 42 Apr 7 09:30 myscript.sh
No x permission! New files never get execute permission by default — that’s a safety feature. Fix it:
chmod u+x myscript.sh # Or chmod 755 myscript.sh
./myscript.sh # Hello from script!
The umask: Why Defaults Are What They Are
The umask controls default permissions for new files. Check yours:
umask
Typical output: 0002. The umask is subtracted from the base:
- Files base:
666(no execute by default) →666 - 002 = 664→rw-rw-r-- - Directories base:
777→777 - 002 = 775→rwxrwxr-x
From Java: In CSCD 210, file access was mostly invisible — the JVM and OS handled it. Java’s
File.setReadable()exists but you probably never used it. In C and Unix, permissions are fundamental. You’ll encounter them when compiling programs (needx), reading input files (needr), and writing output files (needw). Getting “Permission denied” is one of the most common errors, and now you know how to fix it.
Checking Detailed File Info
stat testfile.txt
This shows permissions in both octal and symbolic notation, plus owner, group, size, and timestamps. Useful when ls -l doesn’t give you enough detail.
Who Am I? What Groups Am I In?
id # Your user ID, group ID, and all groups
groups # Just your group memberships
cat /etc/passwd | head -5 # All user accounts on the system
Common Pitfall: Never use
chmod 777as a quick fix. It means “anyone on this system can read, write, and execute this file.” On a shared server, that’s a security violation. On a grading server, it might let other students copy your work. Fix the specific permission that’s missing instead.
./myprogram, but get "Permission denied." You check with ls -l and see -rw-r--r--. What's the fix?x in -rw-r--r-- tells you. chmod u+x adds execute for the owner, which is the minimum needed. Option A works but gives everyone full access — a security problem. Option B adds read permission, which is already there. Option C uses root privileges to bypass the problem instead of fixing it.
Why does this matter?
In C development, gcc normally sets the execute bit on compiled output automatically. But if you’re writing shell scripts, creating test runners, or working with Makefile targets, you’ll need to set permissions yourself. Understanding the permission model prevents the “just chmod 777 everything” habit that causes real security problems on shared servers.
Recursive Changes
To change permissions on a directory and everything inside it:
chmod -R 755 myproject/
Be careful — this applies the same permissions to files and directories, which may give execute permission to files that shouldn’t have it.
Quick Check: What does chmod 640 secret.txt do?
Sets permissions to rw-r-----: owner can read and write (6 = 4+2), group can read only (4), and other has no access (0).
Quick Check: Why can you modify a file inside a directory even if the directory doesn't have write permission?
Directory write permission controls creating and deleting files in the directory. Modifying a file’s contents uses the file’s write permission, not the directory’s. These are separate operations.
Quick Check: A file has permissions r-x------. Can the owner modify it?
No. The owner has read and execute but not write (r-x). The owner would need to chmod u+w the file first. However, the owner can always change the permissions back since they own the file.
Permissions Are Your First Security Lesson
File permissions are the simplest form of access control in Unix, and they set the stage for everything else in computer security. When you set a file to 600, you’re saying “only I can see this.” When you set a directory to 755, you’re saying “everyone can browse, but only I can change things.”
These concepts scale up: server configurations, SSH keys, database access, Docker containers — they all build on this same owner/group/other model.
Next up: I/O redirection and pipes. You’ve been seeing command output on your screen, but what if you want to send it to a file? Or chain multiple commands together? That’s where Unix gets really powerful.
Big Picture: In C, you’ll use functions like
fopen()that can fail with “Permission denied” if the file permissions don’t allow the requested access. Understanding permissions now means you’ll debug those errors instantly in Week 8 instead of staring at a cryptic error message.