Linux Basics
Permissions & Sudo
Linux enforces strict ownership rules on every file, directory, and device. Understanding permissions is not optional — it is the reason idf.py flash either works or throws a "Permission Denied" error.
The Permission Model
Every object in Linux (file, directory, device) has three access categories:
| Category | Symbol | Who |
|---|---|---|
| Owner | u (user) | The user who created the file |
| Group | g | Other members of the file's assigned group |
| Others | o | Every other user on the system |
Each category has three independent permission bits:
| Permission | Symbol | Numeric | On a File | On a Directory |
|---|---|---|---|---|
| Read | r | 4 | View file contents | List directory contents |
| Write | w | 2 | Modify / delete file | Create or delete files inside |
| Execute | x | 1 | Run as a program | Enter the directory with cd |
Reading ls -l Output
ls -l /dev/ttyUSB0
crw-rw---- 1 root dialout 188, 0 May 9 09:15 /dev/ttyUSB0
↑ ↑ ↑ ↑
│ │ │ └── Group: dialout
│ │ └──────── Owner: root
│ └─────────── Hard link count
└─────────────────────── Type + Permissions
Breaking down crw-rw----:
| Characters | Meaning |
|---|---|
c | File type: c = character device, d = directory, - = regular file, l = symlink |
rw- | Owner (root) can read and write |
rw- | Group (dialout) can read and write |
--- | Others have no access at all |
So to talk to the ESP32 serial port, your user account must be in the dialout group.
chmod — Change Permissions
Symbolic Mode (readable)
# Add execute to owner
chmod u+x script.sh
# Remove write from group and others
chmod go-w sensitive.conf
# Set exact permissions: owner=rwx, group=rx, others=nothing
chmod u=rwx,g=rx,o= program
# Add execute for everyone
chmod +x deploy.sh
Octal (Numeric) Mode
Each permission set (owner, group, others) is a 3-bit binary number:
| Binary | Octal | Permissions |
|---|---|---|
| 000 | 0 | --- |
| 001 | 1 | --x |
| 010 | 2 | -w- |
| 011 | 3 | -wx |
| 100 | 4 | r-- |
| 101 | 5 | r-x |
| 110 | 6 | rw- |
| 111 | 7 | rwx |
Combine three digits for owner, group, others:
chmod 755 script.sh # rwxr-xr-x (owner all, group+others read+exec)
chmod 644 config.txt # rw-r--r-- (owner read+write, others read only)
chmod 600 private.key # rw------- (owner only)
chmod 777 public/ # rwxrwxrwx (everyone has everything — avoid for security)
chmod 000 locked.txt # ---------- (no one can do anything)
Recursive chmod
chmod -R 755 ./scripts/ # Apply to directory and all contents
chown — Change Ownership
# Change owner
sudo chown rajath file.txt
# Change owner and group
sudo chown rajath:dialout /dev/ttyUSB0
# Recursively change ownership of a directory
sudo chown -R rajath:rajath ~/projects/
sudo — Superuser Do
sudo runs a single command as the root user (or any other user). It prompts for your password (not root's) and logs the action.
sudo apt install git # Install system software
sudo systemctl restart nginx # Restart a service
sudo nano /etc/hosts # Edit a system config file
sudo -u www-data python3 app.py # Run as a different user (www-data)
sudo -i # Open an interactive root shell (use sparingly)
sudo !! # Re-run the last command with sudo
The sudoers File
/etc/sudoers controls who is allowed to use sudo and with what restrictions. Never edit it directly — always use:
sudo visudo
Common entry patterns:
# Allow rajath to run everything as root without password
rajath ALL=(ALL) NOPASSWD: ALL
# Allow the deploy user to only restart a specific service
deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart myapp.service
Groups — The Right Way to Grant Access
Instead of using sudo for device access, add your user to the appropriate group. This is the professional approach.
Important Groups for Embedded Development
| Group | Grants Access To |
|---|---|
dialout | Serial ports: /dev/ttyUSB*, /dev/ttyACM* |
gpio | GPIO pins on Raspberry Pi |
i2c | I2C bus: /dev/i2c-* |
spi | SPI bus: /dev/spidev* |
video | Camera and video devices |
docker | Docker daemon (run Docker without sudo) |
sudo | Full sudo access |
Managing Groups
# Show your current group memberships
groups $USER
id $USER
# Add user to a group (log out and in for changes to take effect)
sudo usermod -aG dialout rajath
sudo usermod -aG docker rajath
# Create a new group
sudo groupadd embedded_devs
# Add multiple users to a group at once
sudo usermod -aG embedded_devs alice
sudo usermod -aG embedded_devs bob
# Remove a user from a group
sudo gpasswd -d rajath plugdev
# View all groups and their members
cat /etc/group | grep dialout
Special Permission Bits
setuid (s on owner execute)
When set on an executable, it runs with the owner's privileges regardless of who executes it. Example: /usr/bin/passwd runs as root so it can write to /etc/shadow.
chmod u+s /usr/bin/some_tool
# Appears as: -rwsr-xr-x
setgid (s on group execute)
When set on a directory, new files created inside inherit the directory's group instead of the creator's default group. Useful for shared project directories.
chmod g+s shared_project/
# Appears as: drwxrwsr-x
Sticky Bit (t on others execute)
When set on a directory, only the file's owner (or root) can delete it — even if others have write access. The classic example is /tmp.
chmod +t /shared/uploads/
# Appears as: drwxrwxrwt
Practical: Fixing the "Permission Denied" on ESP32
This is the most common error new embedded developers hit.
# Error: idf.py flash
# A fatal error occurred: Could not open /dev/ttyUSB0, the port doesn't exist
# Step 1: Check the device exists
ls -la /dev/ttyUSB0
# crw-rw---- 1 root dialout 188, 0 May 9 09:15 /dev/ttyUSB0
# Step 2: Check your groups
groups $USER
# rajath : rajath adm sudo plugdev
# Notice: "dialout" is NOT in the list!
# Step 3: Add yourself to dialout
sudo usermod -aG dialout $USER
# Step 4: IMPORTANT — log out and log back in
# Step 5: Verify
groups $USER
# rajath : rajath adm dialout sudo plugdev
Quick Reference
| Command | Effect |
|---|---|
ls -l file | View permissions |
chmod +x file | Add execute permission |
chmod 644 file | Set rw-r--r-- |
chmod 755 file | Set rwxr-xr-x |
chmod -R 755 dir/ | Recursive permission change |
chown user:group file | Change owner and group |
sudo cmd | Run one command as root |
groups $USER | Show group memberships |
sudo usermod -aG grp user | Add user to group |
sudo visudo | Edit sudoers safely |

