Linux User Management and Sudo – Foundations
User Types in Linux
In Linux, users are generally divided into three main categories.
Understanding these categories is very important because permissions, security, and system management depend on them.
1. System Accounts
System accounts are used by the operating system itself.
- They run background services and processes
- Examples: web servers, databases, system daemons
- They usually do not have a home directory
- They are not meant for human login
2. Regular Users
Regular users are normal human users of the system.
- Each regular user has a home directory (for example:
/home/username)
They can:
- Create files
- Edit files
- Browse their own directories
They cannot:
- Pe…
Linux User Management and Sudo – Foundations
User Types in Linux
In Linux, users are generally divided into three main categories.
Understanding these categories is very important because permissions, security, and system management depend on them.
1. System Accounts
System accounts are used by the operating system itself.
- They run background services and processes
- Examples: web servers, databases, system daemons
- They usually do not have a home directory
- They are not meant for human login
2. Regular Users
Regular users are normal human users of the system.
- Each regular user has a home directory (for example:
/home/username)
They can:
- Create files
- Edit files
- Browse their own directories
They cannot:
- Perform administrative tasks
- Access other users’ files
- Change system configuration
During Ubuntu installation, the user you create is a regular user by default.
3. Super User (Root)
The super user, also called root, has unrestricted access to the system.
The root user can:
- Access all files, including other users’ home directories
- Add or remove users
- Install or remove software
- Change system configuration
- Perform any administrative task
There are no restrictions for the root user.
Because of this power, direct root usage is dangerous and is avoided in real environments.
Regular User in Practice
When you log in as a regular user, you can:
- Browse files
- Create and edit files
- Use applications
However, you cannot perform system administration tasks.
For example:
- Opening Settings → Users
- Trying to add or modify users
You will see that:
- You cannot add users
- You cannot change settings
This is expected behavior for a regular user.
Why We Need Temporary Privileges
In real systems, we often need to:
- Install software
- Update the system
- Manage users
- Change system configuration
We do not want to log in as root all the time.
Instead, Linux provides a safe mechanism called sudo.
What Is sudo?
sudo stands for “superuser do”.
It allows a regular user to temporarily gain elevated (root) privileges.
Key points:
- Privileges apply only to that command
- You use your own user password, not the root password
- The command runs as root
Example: Accessing Root’s Home Directory
The root user’s home directory is:
/root
A regular user cannot access this directory.
If you try:
ls /root
You will get:
Permission denied
But with sudo:
sudo ls /root
- You are prompted for your password
- The command executes with root privileges
- Access is granted
Important Notes About sudo
- Not all users have
sudoaccess
During installation, you may need to enable:
- “Make this user an administrator”
If sudo does not work:
- You will see a permission error
- This can be fixed (no reinstall needed)
- We will troubleshoot this in the next lecture
For now, assume sudo is working.
Creating Another User (Example)
Using administrative privileges, you can create new users.
When creating a standard user:
The user gets:
- A home directory
The user does not get:
sudoprivileges by default
Each user’s home directory is private and protected.
Accessing Other Users’ Home Directories
As a regular user:
cd /home/otheruser
Result:
Permission denied
With sudo:
sudo ls /home/otheruser
Now access is allowed.
This clearly shows how powerful sudo is.
⚠️ WARNING: Be Extremely Careful with sudo
sudo gives you root power.
If you run a dangerous command, Linux will not stop you.
For example (DO NOT RUN):
sudo rm -rf /etc
- This deletes critical system files
- The system will break
- The OS may fail to boot
In virtual machines, this is recoverable. In real production systems, this can cause serious outages.
Key Takeaways
- Linux has system users, regular users, and root
- Regular users are restricted by default
- Root has unlimited power
sudoallows temporary privilege escalationsudomust be used carefully and intentionally
This foundation is critical for:
- Package management
- System updates
- DevOps and production environments
In the next lecture, we will focus fully on:
- How
sudoworks internally - How to configure it safely
- How to troubleshoot
sudoissues
What to Do If sudo Does Not Work
Important Clarification
Even if a regular user can use sudo, that user is still not the super user (root).
sudoonly allows temporary privilege escalation- You always enter your own user password
- You do not become root permanently
Why sudo Might Not Work
If sudo does not work, it usually means:
- Your regular user was not granted administrative privileges during installation
- This is common on some systems (especially CentOS)
In this case:
sudocommands will fail- Administrative actions will request the root password, not your user password
How to Recognize the Problem (GUI Example)
When opening Settings → Users:
Clicking Unlock may ask for:
- Administrator password
- Not your regular user password
If the system asks for the root password, your user:
- Does not have
sudoprivileges - Is a standard regular user only
If sudo were enabled:
- It would ask for your own user password
Solution 1: Create a New Administrator User (Recommended)
Instead of modifying the existing user, the simplest and safest approach is:
- Log in using the root account (or authenticate with root password)
- Create a new user
- Set the account type to Administrator
- Assign a strong password
⚠️ Note:
- Some systems enforce strict password policies
- Simple passwords may be rejected
- This is normal and expected
Once created:
- This new user will have
sudoprivileges - A home directory will be created automatically
Switching to the New Admin User
- Log out of the current session
- Log in as the new administrator user
- Open a terminal
Now test:
sudo ls /root
- The system asks for your user password
- Access is granted
sudois working correctly
Verifying Permissions
As a regular user:
ls /home/otheruser
Result:
Permission denied
With sudo:
sudo ls /home/otheruser
Access is granted.
This confirms:
- User isolation is enforced
sudoallows controlled privilege escalation
Optional: Fix the Original User
Once logged in as an administrator:
- Go back to Settings → Users
- Unlock using your admin user password
- Change the original user’s role to Administrator
After logging out and back in:
- The original user will also have
sudoaccess
Summary: Fixing sudo Issues
If sudo does not work:
- Your user lacks administrative privileges
- Create a new administrator user
- Log in with that user
- Optionally upgrade the original user later
This works on:
- Ubuntu
- CentOS
- Most Linux distributions
Introduction to Package Management (Concept)
Now that we understand permissions and sudo, we can talk about package management.
What Is Package Management?
Package management is a system that allows you to:
- Install software
- Update software
- Remove software
- Keep the system secure and consistent
Almost all Linux distributions include a package manager.
This is one of Linux’s biggest strengths.
Why Package Management Is Important
- Centralized software updates
- No need for individual app updaters
- System stays consistent and secure
For example:
- Firefox and Chrome usually do not update themselves
- Updates are handled by the OS package manager
How Package Management Works
- The system connects to central repositories
- Repositories provide:
- Available packages
- Versions
Dependencies
- The package manager:
Downloads a package list
Resolves dependencies automatically
Installs everything required
This process is:
- Automatic
- Reliable
- Widely used in production systems
Distribution Differences
- Ubuntu and CentOS use different tools
- The concept is the same
- The commands differ
That’s why:
- Ubuntu package management
- CentOS package management are covered in separate lectures
Package Management on Ubuntu (APT Basics)
Why sudo Is Required
When running:
apt update
You may see:
Permission denied
Reason:
- APT needs access to system files
Solution:
sudo apt update
This updates the package list, not the software itself.
Updating Installed Software
Small Upgrade (Safe)
sudo apt upgrade
- Upgrades installed packages
- Installs required dependencies
- Does not remove packages
This is the safest upgrade option.
Full Upgrade (Advanced)
sudo apt full-upgrade
(or)
sudo apt dist-upgrade
- Upgrades packages
- May remove unused dependencies
- May remove old packages
⚠️ Use only if you:
- Have time to troubleshoot
- Understand potential risks
Installing Software
Example:
sudo apt install cowsay
- Installs the package
- Automatically resolves dependencies
Using the program:
cowsay Hello from Ubuntu
Removing Software
sudo apt remove cowsay
- Removes the package
- Leaves unused dependencies behind
Cleaning Unused Packages (Troubleshooting)
sudo apt autoremove
- Removes unused dependencies
- Often fixes upgrade issues
- Safe to run when needed
APT vs APT-GET (Important Note)
Both work with the same system:
apt→ newer, user-friendlyapt-get→ older, script-friendly
Key difference:
apt upgrade→ installs dependenciesapt-get upgrade→ does not install new dependencies
You may see both used in this course.
Key Takeaways
sudois required for system changes- Package managers keep systems secure
- Ubuntu uses APT
- Always update before installing software
- Prefer
apt upgradefor daily maintenance - Use
full-upgradecarefully
`
Package Management and Bash
you will learn:
- How to create directories and files in Bash
- How to copy, move, and rename files (renaming is done using the same command as moving)
- How to delete files and directories
- Why Bash can be dangerous if used incorrectly
- How to protect yourself from accidental data loss
You will also solve real-world problems, such as:
- Extracting all photos from a complex folder structure (for example, from an SD card)
- Finding and extracting specific PDF files from nested directories
Package Management on macOS: Homebrew
Unlike Linux, macOS does not include a built-in system-wide package manager.
To install software from the command line, we use Homebrew.
Homebrew describes itself as:
“The missing package manager for macOS”
This description is very accurate, especially if you work a lot in the terminal.
Installing Homebrew
To install Homebrew:
- Open a browser
- Go to the Homebrew website
- Copy the installation command shown there
The command:
- Uses Apple’s built-in Bash
- Downloads a script
- Executes it to install Homebrew
⚠️ Security note Running a script downloaded from the internet always carries some risk. In this case, we trust Homebrew because it is widely used and well-maintained.
Running the Installer
- Open Terminal on macOS
- Paste the install command
- Press Enter
- Enter your password if prompted
- Follow the on-screen instructions
Once the installation finishes, Homebrew is ready to use.
Using Homebrew
Updating Package Definitions
brew update```
This updates Homebrew’s package list\.
Unlike Linux:
- Homebrew usually **does not require sudo**
- It installs software in user-controlled directories
---
### Installing Software
To install a package:
```bash
brew install <package-name>```
Example:
```bash
brew install bash```
This installs a modern version of Bash \(version 5\.x\)\.
---
### Upgrading Installed Software
To upgrade all installed packages:
```bash
brew upgrade```
---
## Installing and Using Bash 5 on macOS
After installing Bash with Homebrew, a **new Bash version** is available on your system\.
---
## Launching the New Bash
In most cases, you can simply run:
```bash
bash```
Then verify the version:
```bash
echo $BASH_VERSION```
If the version starts with **5**, you are good to go\.
---
## If Bash Is Still Version 3
On some systems, `bash` may still start Apple’s old Bash \(version 3\)\.
In that case, start Homebrew’s Bash explicitly:
```bash
/opt/homebrew/bin/bash```
\(Apple Silicon Macs\)
or use tab completion to locate the correct path\.
This will **always** launch Bash 5\.x\.
---
## Apple Bash Still Exists
Nothing is removed\.
You can still launch Apple’s original Bash with:
```bash
/bin/bash```
This keeps the system safe and compatible\.
---
## Important Differences on macOS
Although Bash works very similarly, there are some differences to be aware of\.
### Home Directory Path
On macOS:
```text
/Users/yourname```
On Linux:
```text
/home/yourname```
---
### Folder Names and Language
Even if your macOS language is not English:
- Finder may show translated names \(e\.g\. “Dokumente”\)
- The **actual folder name** on disk is still:
```text
Documents```
This is important when navigating in the terminal\.
---
## Safety Warning for macOS Users
When using Bash **directly on macOS**:
- You are working on your **real system**
- A single wrong command \(for example `rm -rf`\) can delete real files
That is why:
- A **virtual machine is still recommended**
- Especially for beginners
However:
- For Bash basics
- For scripting practice
You can safely do **a large portion of the course** directly on macOS if you are careful\.
## File Management Basics in Bash
## `touch`, `mkdir`, `mv`, and `cp`
- `touch` – create files and update timestamps
- `mkdir` – create directories
- `mv` – move and rename files
- `cp` – copy files and directories
These commands are used **every day** in real Linux and DevOps environments\.
---
## 1\. Creating Files with `touch`
The `touch` command is typically used to **create empty files**\.
It can also create **multiple files at once**\.
### Creating a Single File
Assume we are already inside an empty directory:
```bash
touch invite.txt```
Now list the contents:
```bash
ls```
You will see:
```invite.txt```
---
### Creating Multiple Files at Once
```bash
touch anna.txt max.txt eva.txt```
List again:
```bash
ls```
All files are created in one command\.
---
### Why Is It Called `touch`?
The main purpose of `touch` is **not just file creation**\.
What it actually does:
- If the file **exists** → updates its timestamp
- If the file **does not exist** → creates an empty file with the current timestamp
---
### Viewing File Timestamps
Use the `-l` flag with `ls`:
```bash
ls -l```
This shows:
- Permissions
- Owner
- Size
- **Last modified timestamp**
Now touch an existing file again:
```bash
touch invite.txt
ls -l```
You will see that the **timestamp has changed**\.
---
## 2\. Creating Directories with `mkdir`
The `mkdir` command is used to create **directories \(folders\)**\.
### Example
```bash
mkdir ready```
List contents:
```bash
ls```
You now have:
- Files
- One directory \(`ready`\)
---
### Showing Colors \(Optional\)
On most systems:
```bash
ls --color=auto```
- Directories appear in a different color
- Files remain a normal color
This helps visually distinguish files and folders\.
---
## 3\. Moving Files with `mv`
The `mv` command is used to:
- Move files
- Rename files
- Move and rename at the same time
---
### Moving a File into a Folder
```bash
mv anna.txt ready/```
Confirm without changing directories:
```bash
ls ready```
The file is now inside the `ready` folder\.
---
### Renaming a File
```bash
mv max.txt maximilian.txt```
List contents:
```bash
ls```
The file has been renamed\.
---
### Move and Rename at the Same Time
```bash
mv maximilian.txt ready/max.txt```
This:
- Moves the file into `ready`
- Renames it back to `max.txt`
Check:
```bash
ls ready```
---
## 4\. Copying Files with `cp`
The `cp` command creates a **copy** of a file\.
---
### Copying a File
```bash
cp laura.txt laura_copy.txt```
Now both files exist\.
---
### Copy and Rename in One Step
```bash
cp laura.txt ready/lauren.txt```
This:
- Copies the file
- Renames it during the copy
---
### Copying Multiple Files into a Folder
```bash
cp eva.txt ready/```
---
## 5\. Copying Directories \(Recursive Copy\)
To copy a **directory**, you must use the `-R` flag\.
`-R` means **recursive** \(copy everything inside\)\.
---
### Example: Create a Backup
```bash
cp ready ready_backup```
This will **fail**, because `ready` is a directory\.
Correct command:
```bash
cp -R ready ready_backup```
Now you have:
- `ready`
- `ready_backup`
Both contain the same files\.
---
### Best Practice: Avoid Spaces in Names
Instead of:
```Ready Backup```
Use:
```ready_backup```
Why?
- Spaces require quotes
- Commands become harder to type
- Underscores are safer and standard practice
---
## Summary of Commands
| Command | Purpose |
| ------- | ------- |
| `touch` | Create empty files / update timestamps |
| `mkdir` | Create directories |
| `mv` | Move or rename files |
| `cp` | Copy files |
| `cp -R` | Copy directories recursively |
## Deleting Files and Directories in Bash
## `rm` and `rmdir`
⚠️ **Important warning**:
Deleting files in Bash is **permanent**\.
There is **no recycle bin**, no undo, and usually **no confirmation**\.
Because of this, these commands are some of the **most dangerous** Bash commands\.
---
## 1\. Deleting Files with `rm`
To delete a file, we use the `rm` command\.
### Delete a Single File
```bash
rm invite.txt```
The file is deleted immediately\.
---
### Delete Multiple Files at Once
```bash
rm anna.txt max.txt```
Both files are removed with one command\.
---
## ⚠️ Why `rm` Is Dangerous
When you delete a file using `rm`:
- The file is **gone permanently**
- It does **not** go to Trash / Bin
- You cannot restore it
### Example \(Real Risk\)
If you delete a presentation file:
```bash
rm presentation.pptx```
And then open your Trash:
- The file is **not there**
- It is permanently deleted
This is why you must **always double-check** before pressing Enter\.
---
## 2\. Deleting Directories with `rm -r`
By default, `rm` **cannot delete directories**\.
If you try:
```bash
rm ready_backup```
You will get an error saying it is a directory\.
This is intentional — deleting directories is even more dangerous\.
---
### Recursive Delete \(`-r`\)
To delete a directory, you must explicitly allow it:
```bash
rm -r ready_backup```
- `-r` means **recursive**
- Deletes the directory and **everything inside it**
- Works for empty and non-empty directories
After this command, the folder is **completely gone**\.
---
## 3\. Why Extra Protection Exists
Deleting one file is bad\.
Deleting a **whole directory tree** by accident can be catastrophic\.
That is why:
- `rm` refuses to delete directories by default
- You must explicitly add `-r`
This extra step protects you from accidental data loss\.
---
## 4\. Safer Alternative: `rmdir`
The `rmdir` command means **remove directory**\.
Key behavior:
- It **only deletes empty directories**
- It will **fail** if the directory contains files
### Example
```bash
rmdir ready```
If the directory is **not empty**, you will see:
```Directory not empty```
Nothing is deleted\.
---
## Why `rmdir` Is Safer
If you accidentally run `rmdir` on a directory with files:
- Nothing happens
- Your data is safe
This makes `rmdir` a **much safer choice** when possible\.
---
## 5\. Hidden Files and `rmdir`
Be careful: **hidden files count as files**\.
### Example
Create a directory and a hidden file:
```bash
mkdir images
touch images/.thumbs.db```
List normally:
```bash
ls images```
It looks empty\.
But list all files:
```bash
ls -a images```
You will see:
- `.thumbs.db` \(hidden file\)
Now try:
```bash
rmdir images```
It will fail because the directory is **not empty**\.
---
### Special Entries Explained
When using `ls -a`, you may see:
- `.` → current directory
- `..` → parent directory
These are **not real files**\.
Only `.thumbs.db` is a real file in this example\.
---
## 6\. Correct and Safe Cleanup Process
To safely delete the directory:
```bash
rm images/.thumbs.db
rmdir images```
This approach is:
- Explicit
- Safer
- Less error-prone than `rm -r`
---
## Summary of Deletion Commands
| Command | Purpose | Safety |
| ------- | ------- | ------ |
| `rm file` | Delete file | ⚠️ Dangerous |
| `rm file1 file2` | Delete multiple files | ⚠️ Dangerous |
| `rm -r dir` | Delete directory and contents | 🚨 Very dangerous |
| `rmdir dir` | Delete empty directory | ✅ Safer |
---
## Key Takeaways
- `rm` permanently deletes files
- There is **no undo**
- `rm -r` is extremely dangerous
- Prefer `rmdir` whenever possible
- Always double-check paths before pressing Enter
## File Management – Exercise Solution
## Step 1: Navigate to the Desktop
First, we check our current working directory:
```bash
pwd```
On macOS, the home directory looks like:
```text
/Users/yourname```
Now navigate to the Desktop:
```bash
cd Desktop```
You can also use **Tab completion** to avoid typing everything manually\.
Verify:
```bash
pwd```
You should now be on your Desktop\.
---
## Step 2: Create and Enter `temp_website`
Create a new directory:
```bash
mkdir temp_website```
Move into it:
```bash
cd temp_website```
Confirm:
```bash
pwd```
---
## Step 3: Create Initial Files
Create three files:
```bash
touch index.html style.css script.js```
Verify:
```bash
ls```
You should see all three files\.
---
## Step 4: Create `styles` Directory and Move `style.css`
Create the directory:
```bash
mkdir styles```
Move the file:
```bash
mv style.css styles/```
Verify:
```bash
ls
ls styles```
---
## Step 5: Create `scripts` Directory
Still inside `temp_website`, create:
```bash
mkdir scripts```
---
## Step 6: Move and Rename `script.js`
Move `script.js` into `scripts` and rename it to `index.js` at the same time:
```bash
mv script.js scripts/index.js```
Verify:
```bash
ls scripts```
---
## Step 7: Create `pages/page1.html`
Create a new directory:
```bash
mkdir pages```
Create the file inside it \(without changing directories\):
```bash
touch pages/page1.html```
---
## Step 8: Copy to `page2.html` and `page3.html`
Copy using paths:
```bash
cp pages/page1.html pages/page2.html```
Change into the directory and copy again:
```bash
cd pages
cp page1.html page3.html```
Now go back:
```bash
cd ..```
---
## Step 9: Move `page2.html` One Level Up
Move the file from `pages` into the current directory:
```bash
mv pages/page2.html .```
The dot \(`.`\) means **current directory**\.
---
## Step 10: Delete Unneeded Files
Delete:
- `index.html`
- `pages/page1.html`
- `pages/page3.html`
```bash
rm index.html pages/page1.html pages/page3.html```
---
## Step 11: Rename `page2.html` to `index.html`
```bash
mv page2.html index.html```
---
## Step 12: Remove Empty `pages` Directory
Because `pages` is now empty, use:
```bash
rmdir pages```
---
## Step 13: Delete the Entire Project Directory
First, leave the directory:
```bash
cd ..```
Now delete everything recursively:
```bash
rm -r temp_website```
The project is now completely removed\.
---
## Exercise Summary
This exercise was a **play-along**, but it is extremely important because these commands are used constantly:
- `cd`
- `pwd`
- `touch`
- `mkdir`
- `mv`
- `cp`
- `rm`
- `rmdir`
Practicing them builds muscle memory that you will rely on later\.
---
## Introduction to Globbing \(Filename Expansion\)
We are now ready to talk about **Globbing**, also called **filename expansion**\.
This is one of the reasons why Bash is:
- Very compact
- Extremely powerful
---
## What Is Globbing?
Globbing is a process where **Bash rewrites your command before it is executed**\.
It:
- Recognizes **wildcard characters**
- Matches file patterns
- Expands them into real file names
This happens **before** the command runs\.
---
## Example Without Globbing
Imagine a folder containing:
```text
image1.jpeg
image2.jpeg
image3.jpeg
movie.mp4
info.txt```
To move images manually:
```bash
mv image1.jpeg image2.jpeg image3.jpeg images/```
This works, but it is inefficient\.
---
## Using the `*` Wildcard
The `*` \(asterisk\) means:
> Match zero or more characters
Move all JPEG files at once:
```bash
mv *.jpeg images/```
Bash expands this internally to:
```bash
mv image1.jpeg image2.jpeg image3.jpeg images/```
You didn’t type that — **Bash did it for you**\.
---
## Why This Is Powerful
- Works with 3 files or 300 files
- Reduces errors
- Saves time
- Makes scripts scalable
---
## Globbing Works with Any Command
Globbing is a **shell feature**, not a `mv` feature\.
Example:
```bash
echo *.jpeg```
Bash expands the wildcard and prints the file names\.
The command itself has no idea globbing happened\.
---
## What Happens If Globbing Finds Nothing?
If no files match:
```bash
mv *.jpeg images/```
Bash passes `*.jpeg` as a literal string\.
Result:
- `mv` fails
- File does not exist
This behavior is specific to Bash and differs in other shells like Zsh\.
---
## Disabling Globbing with Quotes
Wildcards are **not expanded** inside quotes\.
```bash
echo "*.jpeg"```
Output:
```text
*.jpeg```
No expansion occurs\.
---
## Creating Files with Wildcard Characters
If you want a literal filename like:
```text
*.jpeg```
Use quotes:
```bash
touch "*.jpeg"```
Now it is a real file name\.
---
## Working with Such Files
Always disable globbing:
```bash
mv "*.jpeg" new.jpeg```
This treats it as a literal filename\.
---
## Globbing ≠ Regular Expressions
Important clarification:
- Globbing is **not** regex
- Syntax is different
- Use cases are different
## Globbing – Additional Wildcards
-
`*` \(asterisk\) → matches **zero or more characters**
-
`?` \(question mark\)
-
`[ ]` \(character ranges\)
-
`**` \(globstar – recursive matching\)
---
## 1\. The Question Mark `?`
The question mark matches **exactly one single character**\.
### Comparison
| Wildcard | Matches |
| -------- | ------- |
| `*` | Zero or more characters |
| `?` | Exactly one character |
---
### Example
Assume we have these files:
```text
IMG_6677.mkv
IMG_6677.srt```
To match both files:
```bash
echo IMG_?677.*```
Explanation:
- `IMG_` → fixed prefix
- `?` → matches exactly one character
- `677` → fixed digits
- `.*` → any extension
Both files are matched\.
---
### Why `?` Is Useful
If filenames differ by **only one character**, `?` allows you to match them without matching too much\.
---
## 2\. Character Ranges `[ ]`
Square brackets allow you to match **exactly one character from a defined range**\.
### Examples
| Pattern | Meaning |
| ------- | ------- |
| `[0-9]` | One digit |
| `[a-z]` | One lowercase letter |
| `[A-Z]` | One uppercase letter |
---
### Example with Images
Assume we have files like:
```text
IMG_6001.jpeg
IMG_6123.jpeg
IMG_7450.jpeg```
To match only images starting with `IMG_6` and followed by **three digits**:
```bash
echo images/IMG_6[0-9][0-9][0-9].*```
Explanation:
- `IMG_6` → fixed prefix
- `[0-9][0-9][0-9]` → exactly three digits
- `.*` → any extension
This matches files starting with `IMG_6xxx`\.
---
### Important Limitation
Normal globbing **does not support repetition counts** like `{3}`\.
So this does **not** work in standard globbing:
```text
[0-9]{3}```
You must repeat the range manually\.
---
### Practical Note
In real life, most people simply use:
```bash
IMG_6*```
The asterisk is often **simpler and more practical**\.
---
## 3\. The Double Asterisk `**` \(Globstar\)
The double asterisk matches:
- Zero or more characters
- **Including directory separators \(`/`\)**
This allows **recursive matching**\.
---
### Requirements
- Bash **4\.0 or higher**
- `globstar` must be enabled:
```bash
shopt -s globstar```
---
### Example: Find All JPEG Files Recursively
```bash
echo **/*.jpeg```
Explanation:
- `**/` → any directory depth
- `*.jpeg` → all JPEG files
This finds JPEG files in:
- Current directory
- Subdirectories
- Nested folders
---
### Why the Slash Matters
This is correct:
```bash
**/*.jpeg```
This is wrong:
```bash
**.jpeg```
Without the slash, Bash would look for a file literally named `something.jpeg` inside a folder\.
---
### Combining Globstar with Commands
Example: Copy all JPEG and MOV files into the current directory:
```bash
cp **/*.jpeg **/*.mov .```
- Both patterns are expanded
- Last argument \(`.`\) is the destination
---
## 4\. Why Globbing Is So Powerful
One command can:
- Traverse directories
- Match hundreds of files
- Replace complex manual work
This is why Bash is:
- Compact
- Extremely powerful
- Widely used in automation
---
## ⚠️ Be Careful with Globbing
Globbing is powerful — **and dangerous** if used incorrectly\.
---
## The Core Problem
Bash does **not distinguish** between:
- Filenames
- Command parameters
Everything is just **arguments**\.
---
### Dangerous Scenario
A file can legally be named:
```text
-rf```
Now imagine this command:
```bash
rm *```
Bash expands `*` to:
```bash
rm -rf documents important.txt```
Now:
- `-r` → recursive
- `-f` → force
- Confirmation is bypassed
- Entire directories may be deleted
This can cause **massive data loss**\.
---
## Demonstration
Files and folders:
```text
important.txt
letter.txt
documents/
documents/presentation.txt```
Now create a dangerous filename safely:
```bash
touch ./-rf```
The `./` ensures it is treated as a filename\.
---
### Expansion Example
```bash
echo *```
Expands to:
```text
-rf documents important.txt letter.txt```
Now if used with `rm`, behavior changes drastically\.
---
## ✅ Best Practice: Always Use `./*`
Instead of:
```bash
rm *```
Use:
```bash
rm ./*```
Why this is safer:
- `./-rf` is now clearly a filename
- It cannot be interpreted as a parameter
- Commands behave predictably
---
### Example
```bash
rm ./*```
- Files are deleted
- Directories are **not deleted** unless `-r` is explicitly provided
This dramatically reduces risk\.
---
## Key Safety Rule
> **Always prefix wildcards with `./` when working in the current directory\.**
This one habit prevents many real-world accidents\.
---
## Summary: Globbing Safety
- Globbing happens **before command execution**
- Filenames can become parameters
- `*` can expand into dangerous arguments
- `./*` forces filenames, not options
- Power requires responsibility
---
## Globbing Exercise
## Scenario
You work for a company and must urgently provide documents for **January and February**\.
Requirements:
- Extract **Excel and PDF files**
- From **multiple departments**
- Across **nested folder structures**
---
## Folder Structure \(Provided as ZIP\)
- Departments \(e\.g\. `sales`, `purchasing`\)
-
Monthly folders:
- `01_January`
- `02_February`
-
Files:
- `.xlsx`
- `.pdf`
- Other irrelevant files
---
## Your Goal
Use **globbing** to:
- Select only January and February
- Select only PDF and Excel files
- Work across all departments
- Copy results into one destination
---
## Helpful Tips
### Character Ranges
```text
[0-2]```
Matches:
- `0`
- `1`
- `2`
Useful for months\.
---
### Combining Patterns
You can use multiple glob patterns in one command:
```bash
cp pattern1 pattern2 destination/```
Both patterns expand before execution\.
---
### Practical Advice
- Extract the ZIP
- Navigate to the root folder
- Try solving it **yourself first**
- Observe how compact Bash solutions can be
## Globbing Exercise – Sample Solution
## Viewing the Directory Structure
First, listed the directory structure in my terminal using the `tree` command:
```bash
tree```
This command displays the folder structure in a tree-like format\.
⚠️ **Note**:
You may need to install `tree` first, depending on your system\.
This output is similar to what you saw earlier in the file browser\.
---
## Understanding the Task
We need to:
- Go through **multiple department folders** \(for example, `purchasing` and `sales`\)
- Enter **January and February** only
-
Collect:
- **Excel files \(`.xlsx`\)**
- **PDF files \(`.pdf`\)**
-
Copy them into a single destination folder
The folders cannot be reliably selected by name, but they **can be selected by number**:
- January → `01`
- February → `02`
This is perfect for globbing\.
---
## Matching January and February
To match January and February folders, we use:
```text
0[1-2]*```
Explanation:
- `0` → folders starting with `0`
- `[1-2]` → match `1` or `2`
- `*` → match the rest of the folder name
---
## Previewing Excel Files \(Safe Check\)
Before copying anything, we preview the result using `echo`:
```bash
echo */0[1-2]*/**/*.xlsx```
This shows all Excel files from:
- Any department
- January and February only
Always preview first when using globbing\.
---
## Creating the Destination Folder
Create a folder to collect the files:
```bash
mkdir export```
---
## Copying Excel Files
Now copy all matching Excel files into the `export` folder:
```bash
cp */0[1-2]*/**/*.xlsx export/```
Verify:
```bash
ls export```
---
## Copying PDF Files
Repeat the process for PDF files:
```bash
cp */0[1-2]*/**/*.pdf export/```
Now the `export` folder contains:
- All Excel files
- All PDF files
- From January and February
- From all departments
---
## Combining Multiple Patterns in One Command
You can also combine multiple patterns in a single `cp` command:
```bash
cp */0[1-2]*/**/*.xlsx */0[1-2]*/**/*.pdf export/```
Both patterns are expanded before execution, and the **last argument** is the destination directory\.
---
## Even Shorter \(Advanced – Preview Only\)
Later in the course, you will learn expansions that allow this:
```bash
cp */0[1-2]*/**/*.{xlsx,pdf} export/```
This is shorter, but it relies on advanced Bash expansions, which we will cover later\.
---
## Why This Matters
What would be very difficult and error-prone in a graphical interface becomes a **one-liner in Bash**\.
This is why Bash is:
- Extremely powerful
- Highly efficient
- Widely used in automation and DevOps
---
## Summary of the Solution
- We used **globbing**, not `find`
- We selected folders by **number ranges**
- We matched multiple file types
- We copied everything with **one or two commands**
This was the intended solution to the exercise\.
---
## Bonus Lecture: The `find` Command
This is a **bonus lecture**\.
That means:
- Not required for the rest of the course
- Very useful to know
- Highly recommended to watch
---
## What Is `find`?
`find` is a standalone program used to **search files and directories** based on many criteria\.
Basic syntax:
```bash
find <path>```
Example \(current directory\):
```bash
find .```
This lists:
- All files
- All folders
- Including hidden system files
---
## Stopping a Long `find` Command
If you accidentally run `find` on a very large directory \(like `/`\):
- It may take a long time
- Press **Ctrl \+ C** to stop it
---
## Filtering by Type
### Find Files Only
```bash
find . -type f```
### Find Directories Only
```bash
find . -type d```
---
## Filtering by Modification Time
Find files modified in the last 7 days:
```bash
find . -type f -mtime -7```
- `-mtime` → modification time
- `-7` → last 7 days
---
## Filtering by File Size
Find files larger than 1 MB:
```bash
find . -type f -size +1M```
This can be useful for:
- Cleanup
- Disk usage analysis
---
## ⚠️ `find` Can Modify Files
`find` is powerful and **can be dangerous**\.
Example: delete empty files:
```bash
find . -type f -empty -delete```
This permanently deletes files\.
Always be careful when combining `find` with actions like `-delete`\.
---
## Getting Help for `find`
Quick help:
```bash
find --help```
Full documentation:
```bash
man find```
Use `q` to exit the manual\.
The `find` command has **many options**, far more than we covered here\.
---
## Key Takeaways
- Globbing is great for **pattern-based selection**
- `find` is better for **complex filtering**
-
`find` can search by:
- Type
- Time
- Size
-
`find` can also **modify or delete files**
-
Always preview before destructive actions
## Reading Files from the Command Line
## 1\. Reading Files with `cat`
The simplest way to read a file is with the **`cat`** command\.
> ⚠️ Note: The correct command is **`cat`**, not `cut`\.
> `cut` is a different tool used for column-based text processing\.
### Basic usage
```bash
cat bash.txt```
This prints the entire contents of the file directly to the terminal\.
### Using globbing with `cat`
Because `cat` accepts multiple file names, you can use globbing:
```bash
cat *.txt```
This prints **all matching files** in order\.
---
## ⚠️ Warning: Do NOT `cat` Binary Files
If you accidentally run `cat` on a binary file \(for example, a JPEG\):
```bash
cat image.jpg```
You may see:
- Garbled output
- Broken terminal behavior
- Cursor issues or strange characters
Some terminals interpret binary control characters, which can **corrupt your terminal session**\.
✅ **If this happens**:
Close the terminal and open a new one\.
---
## 2\. Why `cat` Is Not Enough for Large Files
Imagine a very large text file, such as:
```bash
Romeo.txt # Romeo and Juliet (public domain)```
This file contains **over 5,500 lines**\.
If you run:
```bash
cat Romeo.txt```
Problems occur:
- The terminal buffer is limited
- You cannot scroll back far enough
- The beginning of the file is lost
So we need better tools\.
---
## 3\. Viewing Parts of Files with `head` and `tail`
### `head` – show the beginning of a file
```bash
head Romeo.txt```
By default, this shows the **first 10 lines**\.
To specify the number of lines:
```bash
head -n 20 Romeo.txt```
---
### `tail` – show the end of a file
```bash
tail Romeo.txt```
This shows the **last 10 lines**\.
Useful for:
- Logs
- Recent entries
- End-of-file summaries
---
## 4\. Reading Large Files Properly with `less`
The best tool for reading large text files is **`less`**\.
```bash
less Romeo.txt```
### Why `less` is better
- Loads files efficiently
- Does not overflow the terminal buffer
- Allows interactive navigation
---
### Navigation inside `less`
| Key | Action |
| --- | ------ |
| Arrow keys | Move line by line |
| `F` | Page forward |
| `B` | Page backward |
| `q` | Quit |
| `=` | Show file position |
| `50%` | Jump to 50% of file |
---
### Searching inside `less`
- Forward search:
```text
/word```
- Backward search:
```text
?word```
Example:
```text
/food```
This jumps to the next occurrence of “food”\.
---
### Show line numbers
```bash
less -N Romeo.txt```
This displays **line numbers**, which is very useful for orientation\.
---
## 5\. Counting Lines, Words, and Bytes with `wc`
The **word count** program is `wc`\.
```bash
wc Romeo.txt```
Output format:
```lines words bytes filename```
---
### Common `wc` options
| Option | Meaning |
| ------ | ------- |
| `-l` | Count lines |
| `-w` | Count words |
| `-c` | Count bytes |
Example \(line count only\):
```bash
wc -l Romeo.txt```
This is often used to decide:
- Is the file too large for `cat`?
- Should I use `less` instead?
---
## 6\. Checking File Size with `du` \(Disk Usage\)
The `du` command shows how much disk space a file or directory uses\.
### File size only
```bash
du Romeo.txt```
---
### Summary only \(recommended\)
```bash
du -s Romeo.txt```
---
## ⚠️ macOS vs Linux Disk Size Difference
-
**macOS**
- Default block size: **512 bytes**
-
**Linux**
- Default block size: **1024 bytes \(1 KB\)**
This makes macOS output confusing\.
### Fix: Human-readable output
```bash
du -sh Romeo.txt```
This works consistently across systems\.
---
## 7\. Editing Files from the Command Line
Bash itself does **not** include a text editor\.
You must use an external program\.
---
## Recommended Editor: `nano`
We use **Nano** because:
- Very easy to learn
- Minimal keyboard shortcuts
- Installed by default on many systems
Related editors:
- `pico` → older version
- `nano` → modern rewrite
- `vim` → powerful but steep learning curve \(not used here\)
---
## Installing Nano
### macOS \(Homebrew\)
```bash
brew install nano```
### Ubuntu / WSL
```bash
sudo apt update
sudo apt install nano```
---
## Editing a File with Nano
```bash
nano bash.txt```
If the file does not exist, Nano will create it when you save\.
---
### Basic Nano Controls
| Shortcut | Action |
| -------- | ------ |
| `Ctrl + O` | Save file |
| `Enter` | Confirm filename |
| `Ctrl + X` | Exit |
| Arrow keys | Move cursor |
| `Ctrl + C` | Show cursor position |
| `/` | Search |
Nano shows shortcuts at the bottom of the screen\.
---
## Why Use Nano Instead of VS Code?
Nano is essential when:
- Working on **remote servers**
- Connected via **SSH**
- No graphical interface available
Example:
- Editing server config files
- Quick fixes on production systems
- Emergency changes
For **large projects**, a GUI editor \(like VS Code\) is still preferred\.
## Exercise: Analyzing a Real-World Log File \(Shell-Only\)
The file you receive is **synthetically generated** for privacy reasons, but:
- The **format**
- The **structure**
- The **content patterns**
are all very close to what you would see in production systems\.
---
## Your Tasks
After downloading the log file, answer the following **three questions**:
### 1\. What kind of log file is this?
- What system or application could have generated it?
- What kind of information is being logged?
### 2\. What is the file size?
- Use the **shell only**
- Do **not** check the browser or file explorer
-
Determine the size in:
- KB / MB / GB \(as appropriate\)
### 3\. How many lines does the log file contain?
- Again, use **shell commands only**
---
## Important Rules
- ❌ Do **not** open the file in a GUI editor
- ❌ Do **not** rely on file explorer metadata
- ✅ Use **shell tools only**
- ✅ Pretend this file lives on a **remote server** accessed via SSH
This is exactly how log analysis works in real DevOps / Linux environments\.
---
## Hints
- The file is **small enough** to be analyzed locally \(to keep download sizes reasonable\)
-
In real production systems, log files can be:
- Hundreds of MB
- Several GB
-
Avoid dumping the entire file to the terminal
-
Use tools that allow **controlled inspection**
---
## Sample Solution
Let’s now walk through **one correct way** to solve the exercise\.
---
## Step 1: Inspect the Beginning of the File
Use `head` to preview the first few lines:
```bash
head -n 4 access.log```
What we observe:
- Each line is long \(wrapped visually\)
-
Contains:
- IP addresses \(IPv4 and IPv6\)
- Dates and timestamps
- HTTP methods \(GET\)
- Paths
- HTTP versions
- Status codes
---
## Step 2: Inspect the End of the File
Use `tail`:
```bash
tail access.log```
Or more context:
```bash
tail -n 40 access.log```
Observations:
- Same structure throughout
-
Status codes like:
- `200` \(OK\)
- `302` \(Redirect\)
- `404` \(Not Found\)
-
URLs
-
Browser information \(User-Agent strings\)
---
## Step 3: Identify the Log Type
From the structure we can identify:
- Client IP address
- Timestamp with timezone
- HTTP request method and path
- HTTP version
- Response status code
- Referrer
- User-Agent string
👉 **Conclusion**
This is a **web server access log**, specifically in the
**Apache Combined Log Format**\.
You did **not** need to know the exact name for the quiz — recognizing it as a **web server log** is enough\.
---
## Step 4: Count the Number of Lines
Use `wc` \(word count\):
```bash
wc -l access.log```
Output:
```10000 access.log```
✔ The file contains **10,000 log entries**\.
---
## Step 5: Determine the File Size \(Shell Only\)
Use `du` \(disk usage\)\.
### macOS \(recommended\)
```bash
du -h access.log```
Output \(example\):
```3.0M access.log```
✔ File size is approximately **3 MB**\.
> On macOS, always use `-h` because default block sizes are confusing\.
### Linux \(Ubuntu\)
```bash
du -h access.log```
Linux already reports in kilobytes by default, so the output is usually clearer\.
---
## Why This Approach Matters
You analyzed the file by:
- Viewing **only small parts**
- Avoiding terminal overflow
- Using efficient, safe commands
This scales to:
- Very large log files
- Remote servers
- Production environments
Dumping an entire log file with `cat` would be:
- Inefficient
- Potentially dangerous
- Completely unrealistic in real systems
---
## Final Answers Summary
| Question | Answer |
| -------- | ------ |
| Log type | Web server access log |
| Line count | 10,000 lines |
| File size | ~3 MB |
## Streams in Bash
## Writing Command Output to a File
Let’s start with a simple problem:
> We have a command that produces output\.
> How can we save that output into a file?
### The Wrong Way \(Manual Copy\)
One possible \(but bad\) approach would be:
1. Run a command
1. Select the output with your mouse
1. Copy it
1. Paste it into a text file
1. Save the file
This approach:
- Depends on your terminal and OS
- Breaks with large output
- Is slow and error-prone
- Does not work on remote servers
So this is **not the correct solution**\.
---
## Redirecting Output with `>`
Bash provides a built-in way to redirect output using the **greater-than operator \(`>`\)**\.
### Basic Syntax
```bash
command > file.txt```
What this does:
- Takes the output of `command`
- Writes it into `file.txt`
- If the file does not exist → it is created
- If the file exists → it is **overwritten**
### Example
```bash
echo "Hello Bash" > output.txt```
Now check the file:
```bash
cat output.txt```
Output:
```Hello Bash```
Notice:
- Nothing was printed to the terminal
- The output was written directly to the file
---
### Overwriting Behavior
If we run another command:
```bash
ls > output.txt```
Now the file contains the output of `ls`, and the previous content is gone\.
This is important:
> `>` **always overwrites** the file\.
---
## Appending Output with `>>`
Sometimes we don’t want to overwrite a file\.
Instead, we want to **append** new output to the end\.
For this, we use the **double greater-than operator \(`>>`\)**\.
### Basic Syntax
```bash
command >> file.txt```
What this does:
- Creates the file if it does not exist
- Appends output if the file already exists
### Example
```bash
echo "----" >> output.txt
echo "Another line" >> output.txt```
Check the file:
```bash
cat output.txt```
You will now see multiple lines added to the file instead of overwritten\.
---
### Appending Command Output
You can append output from any command:
```bash
du -h image.jpg >> output.txt```
The result of the `du` command is now added to `output.txt`\.
---
## Important Observation: Errors Are Not Redirected
Let’s look at an example:
```bash
du does_not_exist.txt >> output.txt```
What happens?
- The error message appears **in the terminal**
- Nothing new is added to `output.txt`
Why?
Because **not all output is the same**\.
---
## Why Errors Behave Differently
Bash uses **separate streams**:
- **Standard Output \(stdout\)** – normal command output
- **Standard Error \(stderr\)** – error messages
When you use:
```bash
command > file.txt```
or
```bash
command >> file.txt```
You are **only redirecting standard output**, not errors\.
That’s why:
- Successful output goes into the file
- Errors still appear on the screen
This behavior is **by design** and extremely important\.
---
## Why This Matters
Understanding this allows you to:
- Save only successful output
- Capture only errors
- Discard noisy output
- Debug scripts more effectively
- Write professional-grade Bash commands
This is exactly how real Unix systems are designed to work\.
## Understanding Standard Streams in Bash
To understand why Bash behaved the way it did when we redirected output, we need to understand **standard streams**\.
Every Unix/Linux program communicates with the outside world using **three default streams**\.
---
## The Three Standard Streams
### 1\. Standard Input \(stdin\) — **File Descriptor 0**
- Name: **STDIN**
- Purpose: Input to a program
- Default source: **Keyboard**
If a program reads input \(for example `cat` without a file\), it reads from stdin\.
---
### 2\. Standard Output \(stdout\) — **File Descriptor 1**
- Name: **STDOUT**
- Purpose: Normal program output
- Default destination: **Terminal**
Anything a program prints when everything works correctly goes to stdout\.
---
### 3\. Standard Error \(stderr\) — **File Descriptor 2**
- Name: **STDERR**
- Purpose: Error messages
- Default destination: **Terminal**
Errors are sent to stderr so they can be handled separate