aboutsummaryrefslogtreecommitdiffstats
path: root/linux-command-line/shell-basics/index.md
blob: c0cf75b191c5dd7da7e1dd01b993e8ac2295050d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
---
title: Shell Basics
---

# Shell Basics

The shell is your primary interface to a Linux system. Everything — file management, process control, system administration — flows through it. Before graphical tools, before IDEs, there was the shell. Mastering it is non-negotiable.

**Prerequisites:** None
**Estimated time:** 4-6 hours of practice

---

## What is a Shell?

A shell is a program that reads commands from your input and executes them. It's both a **command interpreter** (runs programs) and a **programming language** (scripts).

Common shells:
- **bash** — Bourne Again Shell, the default on most Linux systems
- **zsh** — Extended bash with better completion and prompting
- **sh** — POSIX shell, the lowest common denominator
- **fish** — Friendly interactive shell, not POSIX-compatible

When you open a terminal, you're running a **terminal emulator** (alacritty, kitty, xterm) which hosts a **shell process**. The terminal draws pixels; the shell interprets commands.

```bash
# Check your current shell
echo $SHELL

# List available shells
cat /etc/shells

# The shell prompt typically shows:
# username@hostname:current_directory$
```

> **Key distinction:** The terminal and the shell are different things. You can run bash inside alacritty, or inside a Linux TTY, or over SSH. The shell doesn't care what's displaying its output.

---

## Navigating the Filesystem

Linux has a single filesystem tree rooted at `/`. Everything is a file — devices, processes, sockets.

### Essential Navigation Commands

```bash
pwd                     # Print working directory — where you are
ls                      # List files in current directory
ls -la                  # Long format, show hidden files (dotfiles)
ls -lh                  # Human-readable sizes (K, M, G)
cd /etc                 # Change to /etc
cd ~                    # Change to home directory (also just: cd)
cd -                    # Change to previous directory
cd ..                   # Go up one level
```

### The Filesystem Hierarchy

| Path | Purpose |
|------|---------|
| `/` | Root of everything |
| `/home` | User home directories |
| `/etc` | System configuration files |
| `/var` | Variable data (logs, databases, mail) |
| `/tmp` | Temporary files (cleared on reboot) |
| `/usr` | User programs and data (read-only) |
| `/usr/bin` | Most user commands |
| `/usr/local` | Locally installed software |
| `/dev` | Device files |
| `/proc` | Process information pseudo-filesystem |
| `/sys` | Kernel/device information pseudo-filesystem |
| `/opt` | Optional/third-party software |

```bash
# The filesystem is a tree. Explore it:
ls /
ls /etc
ls /dev

# Everything is a file:
file /dev/null          # character special device
file /etc/hostname      # ASCII text
file /usr/bin/ls        # ELF 64-bit executable
```

---

## File Operations

### Creating, Copying, Moving, Deleting

```bash
# Create
touch newfile.txt               # Create empty file (or update timestamp)
mkdir mydir                     # Create directory
mkdir -p path/to/nested/dir     # Create nested directories

# Copy
cp file.txt backup.txt          # Copy file
cp -r mydir/ mydir_backup/      # Copy directory recursively

# Move / Rename
mv old.txt new.txt              # Rename
mv file.txt ~/Documents/        # Move to another directory

# Delete
rm file.txt                     # Remove file (no trash, no undo)
rm -r mydir/                    # Remove directory recursively
rm -ri mydir/                   # Interactive — asks before each deletion
rmdir emptydir/                 # Remove only if empty
```

> **Warning:** `rm` is permanent. There is no trash can. `rm -rf /` will destroy your entire system if you have the permissions. Always double-check your path before pressing Enter.

### Viewing Files

```bash
cat file.txt                    # Print entire file to stdout
less file.txt                   # Paginated viewer (q to quit, / to search)
head -n 20 file.txt             # First 20 lines
tail -n 20 file.txt             # Last 20 lines
tail -f /var/log/syslog         # Follow a file in real-time (great for logs)
wc -l file.txt                  # Count lines
```

`less` is your friend. Use it for anything longer than a screenful. Key bindings inside `less`:
- `Space` / `b` — page down / up
- `/pattern` — search forward
- `n` / `N` — next / previous search match
- `g` / `G` — go to top / bottom
- `q` — quit

---

## Permissions

Every file has an **owner**, a **group**, and a set of **permissions** (read, write, execute) for each of: owner, group, others.

```bash
ls -l file.txt
# -rw-r--r-- 1 ahmed users 1234 Mar 31 10:00 file.txt
# │├──┤├──┤├──┤
# │ │    │   └── others: read only
# │ │    └────── group: read only
# │ └─────────── owner: read + write
# └───────────── file type: - = regular, d = directory, l = symlink
```

### chmod — Change Permissions

```bash
# Symbolic notation
chmod u+x script.sh            # Add execute for owner
chmod go-w file.txt            # Remove write for group and others
chmod a+r file.txt             # Add read for all

# Octal notation (most common)
chmod 755 script.sh            # rwxr-xr-x — owner full, others read+execute
chmod 644 file.txt             # rw-r--r-- — owner read+write, others read
chmod 600 secret.key           # rw------- — owner only
```

**Octal cheat sheet:** r=4, w=2, x=1. Add them up per group.
- `7` = rwx (4+2+1)
- `6` = rw- (4+2)
- `5` = r-x (4+1)
- `4` = r-- (4)
- `0` = --- (0)

### chown — Change Ownership

```bash
chown ahmed file.txt            # Change owner
chown ahmed:users file.txt      # Change owner and group
chown -R ahmed:users mydir/     # Recursive
```

### Directories and Execute Permission

The execute bit on directories means something different: it grants **access** (the ability to `cd` into it and access files within). A directory with `r--` lets you list filenames but not read the files. A directory with `--x` lets you access files by name but not list them.

---

## Pipes and Redirection

This is where the shell gets powerful. The Unix philosophy: small programs that do one thing well, connected together.

### Redirection

Every process has three standard streams:
- **stdin** (0) — input
- **stdout** (1) — normal output
- **stderr** (2) — error output

```bash
# Redirect stdout to a file
ls > filelist.txt               # Overwrite
ls >> filelist.txt              # Append

# Redirect stderr
gcc broken.c 2> errors.txt     # Errors go to file
gcc broken.c 2>&1              # Stderr merges into stdout

# Redirect both
command > output.txt 2>&1       # Both to same file
command &> output.txt           # Bash shorthand for the above

# Discard output
command > /dev/null 2>&1        # Silence everything

# Read stdin from a file
sort < unsorted.txt
```

### Pipes

Pipes connect stdout of one command to stdin of the next.

```bash
# Find the 10 largest files in /var/log
du -sh /var/log/* 2>/dev/null | sort -rh | head -10

# Count unique IP addresses in a log
cat access.log | awk '{print $1}' | sort | uniq -c | sort -rn | head -20

# Find running processes matching a pattern
ps aux | grep nginx | grep -v grep

# Chain as many as you need
cat /etc/passwd | cut -d: -f1 | sort | head -5
```

> **Useless use of cat:** `cat file | grep pattern` can be written as `grep pattern file`. But in pipelines with many stages, starting with `cat` can be clearer. Don't stress about it early on — clarity matters more than micro-optimization.

### Command Substitution

Use the output of one command inside another:

```bash
# Using $() — preferred
echo "Today is $(date +%Y-%m-%d)"
files=$(ls *.txt)

# Using backticks — older style, harder to nest
echo "Today is `date +%Y-%m-%d`"
```

---

## Wildcards (Globbing)

The shell expands patterns before passing them to commands:

```bash
*               # Match any characters (except leading dot)
?               # Match exactly one character
[abc]           # Match a, b, or c
[0-9]           # Match any digit
[!abc]          # Match anything except a, b, c
**              # Match directories recursively (bash: shopt -s globstar)

# Examples
ls *.txt                # All .txt files
ls file?.log            # file1.log, fileA.log, etc.
ls *.{jpg,png}          # All .jpg and .png files (brace expansion, not globbing)
rm /tmp/test_*          # All files starting with test_ in /tmp
```

---

## Getting Help

```bash
man ls                  # Manual page for ls (press q to quit)
man -k "copy files"     # Search manual descriptions
ls --help               # Quick help (most GNU tools)
type ls                 # Is it a builtin, alias, or binary?
which python            # Full path of a command
whatis ls               # One-line description
apropos network         # Search man pages by keyword
```

**Reading man pages:** The synopsis section uses conventions:
- `[optional]` — square brackets mean optional
- `REQUIRED` — caps or no brackets means required
- `...` — can be repeated
- `a | b` — choose one

---

## Exercises

### Drill Exercises

1. Navigate to `/etc` and list all files starting with `host`. What do they contain?
2. Create a directory structure: `~/practice/project/{src,docs,tests}` in one command
3. Create a file, set its permissions to 750, then explain who can do what with it
4. Use `ls -la /` and identify which entries are regular files, directories, and symlinks
5. Redirect the output of `ls /nonexistent` to `/dev/null` while keeping error messages visible

### Pipeline Challenges

6. Count how many lines in `/etc/passwd` contain the string `nologin`
7. List the 5 largest files in `/usr/bin` by size (hint: `ls -lS` or `du`)
8. Extract just the usernames from `/etc/passwd` (field 1, colon-separated) and sort them
9. Find all environment variables that contain the string `PATH` (hint: `env | grep`)
10. Get the total line count of all `.conf` files in `/etc/` (hint: `wc -l`, `cat`)

### Mini-Project

**Build a quick reference card:** Create a file `~/cheatsheet.md` that contains the 20 commands you found most useful from this section, organized by category, with a one-line description and example for each. This is your cheatsheet — you'll extend it throughout the course.

---

## Key Takeaways

- The shell is a command interpreter and a programming environment
- Everything in Linux is a file, organized in a single tree from `/`
- Permissions are the foundation of Linux security — understand `rwx` and octal
- Pipes and redirection are the core of composing commands
- `man` and `--help` are always available — read them first, search the web second
- Practice in a real terminal. Reading about commands is not the same as using them.

---

**Next:** [File Management](../file-management/) — find, locate, tar, rsync, and more