Phase 2: Command Line - mishraxharshit/harshitxmishra.github.io GitHub Wiki
Previous: Phase 1: Foundations | Next: Phase 3 — Text Processing
2.1 How the Shell Processes a Command
Before learning individual commands, understand what the shell does when you press Enter.
When you type ls -la /home, the shell performs these steps in order:
- Tokenisation: Splits the line into words:
ls,-la,/home - Alias expansion: Checks if
lsis an alias (e.g.,ls --color=auto) - Variable expansion: Replaces
$HOME,$USER, etc. with their values - Glob expansion: Expands wildcards:
*.txtbecomesfile1.txt file2.txt - Command lookup: Searches
$PATHdirectories to find thelsbinary - Execution: Forks a child process, runs the command, returns the exit code
Understanding this sequence explains many confusing behaviours, like why echo $HOME prints your home directory instead of the literal string $HOME.
2.2 Navigating the Filesystem
# Print Working Directory — where you currently are
pwd
# /home/alice
# Change Directory
cd /var/log # go to absolute path
cd Documents # go to relative path (from current location)
cd .. # go up one level
cd ../.. # go up two levels
cd ~ # go to your home directory
cd - # go to the previous directory (very useful!)
# List files
ls # simple list
ls -l # long format (permissions, owner, size, date)
ls -a # show hidden files (those starting with .)
ls -la # combine both flags
ls -lh # human-readable file sizes (KB, MB, GB)
ls -lt # sort by modification time, newest first
ls -lS # sort by file size, largest first
ls /etc # list a specific directory without going there
Understanding ls -l output:
-rw-r--r-- 1 alice alice 4096 Jan 15 14:22 notes.txt
^ ^ ^ ^ ^ ^ ^
| | | | | | filename
| | | | | last modified date
| | | | file size in bytes
| | | group owner
| | user owner
| number of hard links
file type and permissions
The first character is the file type:
-regular fileddirectorylsymbolic linkbblock device (disk)ccharacter device (terminal, serial port)
2.3 Working with Files and Directories
# Create a directory
mkdir projects
mkdir -p projects/web/css # -p creates parent directories if they don't exist
# Create a file
touch notes.txt # creates empty file, or updates timestamp if exists
echo "Hello" > notes.txt # creates file with content (overwrites if exists)
echo "More" >> notes.txt # appends to file
# Copy files
cp notes.txt backup.txt # copy file to new name in same directory
cp notes.txt /tmp/ # copy to different directory
cp -r projects/ projects_backup/ # -r copies directory recursively
cp -p notes.txt backup.txt # -p preserves permissions and timestamps
# Move and rename (same command)
mv notes.txt renamed.txt # rename file
mv notes.txt /tmp/ # move to different directory
mv projects/ /opt/myprojects # move and rename directory
# Delete
rm notes.txt # delete file
rm -i notes.txt # -i asks for confirmation before deleting
rm -r projects/ # delete directory and all contents recursively
rm -rf projects/ # force delete, no confirmation — use with care
# View file contents
cat notes.txt # print entire file
less notes.txt # page through file (q to quit, / to search)
head -20 notes.txt # first 20 lines
tail -20 notes.txt # last 20 lines
tail -f /var/log/syslog # follow a file in real time as lines are added
The danger of rm -rf:
There is no recycle bin in the Linux terminal. rm -rf /important/data permanently destroys data immediately. The safest habit: always specify exactly what you are deleting, use -i when in doubt, and never run rm -rf / (deletes the entire filesystem).
2.4 File Paths: Absolute and Relative
Every file has two kinds of path:
Absolute path: starts from / and specifies the complete location.
/home/alice/projects/notes.txt
Relative path: starts from your current location.
# If you are in /home/alice:
projects/notes.txt # means /home/alice/projects/notes.txt
# If you are in /home/alice/projects:
notes.txt # means /home/alice/projects/notes.txt
../notes.txt # means /home/alice/notes.txt (one level up)
The special names:
.(single dot) — the current directory..(two dots) — the parent directory~(tilde) — your home directory, expands to/home/yourusername
2.5 Wildcards and Globbing
The shell expands wildcard patterns before passing them to commands. The expansion happens in the shell, not in the command itself.
# * matches any sequence of characters (except /)
ls *.txt # all files ending in .txt
ls report_*.csv # all CSV files starting with report_
rm /tmp/*.log # delete all .log files in /tmp
# ? matches exactly one character
ls file?.txt # matches file1.txt, fileA.txt but not file10.txt
# [...] matches one character from the set
ls file[123].txt # matches file1.txt, file2.txt, file3.txt
ls file[a-z].txt # matches filea.txt through filez.txt
# Practical example: backup all .conf files
cp /etc/*.conf /tmp/conf_backup/
2.6 Input, Output, and Redirection
Every program in Linux has three standard data streams:
- stdin (0): input, by default reads from keyboard
- stdout (1): normal output, by default prints to terminal
- stderr (2): error messages, by default prints to terminal
You can redirect these streams to and from files.
# Redirect stdout to a file (overwrites)
ls -l > directory_listing.txt
# Redirect stdout to a file (appends)
echo "new line" >> notes.txt
# Redirect stderr to a file
ls /nonexistent 2> errors.txt
# Redirect both stdout and stderr to the same file
ls /var /nonexistent > output.txt 2>&1
# 2>&1 means "send stderr (2) to wherever stdout (1) is going"
# Discard output entirely (send to /dev/null, the black hole)
noisy_command > /dev/null 2>&1
# Read stdin from a file
sort < unsorted.txt
# Here document: provide multi-line input inline
cat << EOF
Line one
Line two
Line three
EOF
2.7 Pipes
A pipe | connects the stdout of one command to the stdin of the next. This is one of the most powerful ideas in Unix.
# Count how many files are in /etc
ls /etc | wc -l
# ls prints filenames, wc -l counts lines
# Find the ten largest files in the current directory
ls -lS | head -10
# Find all running processes and search for python
ps aux | grep python
# See which processes are using the most memory
ps aux --sort=-%mem | head -10
# Count how many times a word appears in a file
cat /var/log/syslog | grep "error" | wc -l
# Chain many commands
cat /etc/passwd | cut -d: -f1 | sort | head -10
# /etc/passwd has colon-separated fields, field 1 is username
# cut extracts field 1, sort alphabetises, head shows top 10
The philosophy: Instead of one complex program that does everything, Linux has many small programs that do one thing well, and you compose them with pipes.
2.8 Searching for Files
# find: search by name, type, size, date, permissions
find /home -name "notes.txt"
find /home -name "*.txt"
find /var/log -name "*.log" -mtime -7 # modified in last 7 days
find /tmp -type f -size +10M # files larger than 10MB
find /home -user alice # files owned by alice
find /etc -name "*.conf" -exec ls -l {} \; # run ls -l on each result
# locate: searches a pre-built index (faster but may be out of date)
locate sshd_config
# Update the index
sudo updatedb
# which: find where a command's binary lives
which python3
# /usr/bin/python3
# whereis: find binary, source, and man page
whereis ssh
# ssh: /usr/bin/ssh /etc/ssh /usr/share/man/man1/ssh.1.gz
2.9 Reading Files Efficiently
# cat: print an entire file
cat /etc/hostname
# less: interactive pager (better than cat for large files)
less /var/log/syslog
# Keys inside less:
# Space or f — page down
# b — page up
# /pattern — search forward
# n — next match
# N — previous match
# g — go to beginning
# G — go to end
# q — quit
# head and tail
head /etc/passwd # first 10 lines (default)
head -5 /etc/passwd # first 5 lines
tail /var/log/syslog # last 10 lines
tail -100 /var/log/syslog # last 100 lines
tail -f /var/log/syslog # follow: print new lines as they are added
# wc: word count (also counts lines and characters)
wc -l /etc/passwd # number of lines (= number of user accounts)
wc -w notes.txt # number of words
wc -c notes.txt # number of bytes
2.10 Command History and Shortcuts
These shortcuts save enormous amounts of typing.
# History
history # show command history list
history | grep apt # search history for apt commands
!! # repeat the last command
!ls # repeat the last command starting with 'ls'
!500 # repeat command number 500 from history
Ctrl+R # interactive reverse search through history
Keyboard shortcuts in the terminal:
| Shortcut | Action |
|---|---|
Ctrl+C |
Kill the running command |
Ctrl+Z |
Suspend the running command (resume with fg) |
Ctrl+D |
End of input / log out of shell |
Ctrl+L |
Clear the screen |
Ctrl+A |
Move cursor to beginning of line |
Ctrl+E |
Move cursor to end of line |
Ctrl+W |
Delete the word before the cursor |
Tab |
Auto-complete command or filename |
Tab Tab |
Show all possible completions |
| Up/Down arrows | Scroll through history |
2.11 Links: Hard and Symbolic
A hard link is a second name pointing to the same file data. A symbolic link (symlink) is a file that points to another file by path, like a shortcut.
# Create a hard link
ln original.txt hardlink.txt
# Both names now refer to the same data. Deleting one leaves the other intact.
# Create a symbolic link
ln -s /etc/nginx/nginx.conf ~/nginx.conf
# ~/nginx.conf is a pointer to /etc/nginx/nginx.conf
# See where a symlink points
ls -l ~/nginx.conf
# lrwxrwxrwx 1 alice alice 22 Jan 15 nginx.conf -> /etc/nginx/nginx.conf
# Find broken symlinks (target no longer exists)
find /etc -type l ! -exec test -e {} \; -print
Practical use: Many Linux systems use symlinks extensively. The python command is often a symlink to python3. Nginx configuration uses symlinks to enable/disable sites (a site config lives in sites-available/ and is enabled by symlinking it into sites-enabled/).
Phase 2 Exercises
Exercise 1: Navigate to /var/log. List the files sorted by size (largest first). What are the five largest log files?
Exercise 2: Create a directory structure: ~/practice/scripts/ and ~/practice/data/. Create three text files inside ~/practice/data/. Copy all .txt files from ~/practice/data/ to /tmp/ using a wildcard.
Exercise 3: Use head and tail to read lines 20 through 30 of /etc/passwd. Hint: head -30 /etc/passwd | tail -11
Exercise 4: Count the number of lines in /var/log/syslog. Then count how many of those lines contain the word "error" (case insensitive, use grep -i).
Exercise 5: Use find to locate every file in /etc that was modified in the last 3 days. Save the output to a file called /tmp/recent_changes.txt.
Common Mistakes in Phase 2
Mistake: Using cat to read large files
cat /var/log/syslog on a 500 MB log file will flood your terminal. Use less, head, or tail instead.
Mistake: Forgetting that > overwrites
echo "test" > important_file.txt will destroy whatever was in that file. Use >> to append.
Mistake: Spaces around = in variable assignment
name = alice fails. The shell requires name=alice (no spaces). Spaces make the shell think name is a command.
Mistake: Not using tab completion Typing long paths by hand wastes time and introduces typos. Press Tab after typing the first few letters of any path or command.
Previous: Phase 1 — Foundations | Next: Phase 3 — Text Processing