Linux Administration
Working with Files and Directories
In this lesson
Working with files and directories in Linux goes far beyond simple copy and delete operations. The shell provides powerful mechanisms — wildcards, redirection, pipes, and the find command — that let administrators locate, filter, transform, and chain file operations together into precise, repeatable workflows. These tools are the building blocks of shell scripting and automation.
Wildcards and Globbing
Wildcards (also called glob patterns) are special characters the shell expands into matching filenames before passing them to a command. They allow a single command to act on many files at once without listing each one individually.
| Pattern | Meaning | Example |
|---|---|---|
* |
Matches any number of characters (including none) | ls *.log — all files ending in .log |
? |
Matches exactly one character | ls file?.txt — file1.txt, file2.txt… |
[abc] |
Matches any one character in the set | ls file[123].txt — file1, file2, file3 |
[a-z] |
Matches any one character in the range | ls report[0-9].txt |
[!abc] |
Matches any one character NOT in the set | ls file[!0].txt — excludes file0.txt |
# Delete all .tmp files in the current directory
rm *.tmp
# Copy all .conf files into a backup directory
cp /etc/*.conf /backup/configs/
# List all files starting with "access" in /var/log
ls /var/log/access*
# Match files with exactly one character before .log
ls /var/log/?.log
Analogy: A wildcard in Linux works exactly like a wildcard in a card game — it stands in for whatever is needed. Typing *.log tells the shell to substitute the names of every file that ends in .log before the command even runs.
The find Command
The find command searches the filesystem for files and directories matching specific criteria — name, type, size, modification time, owner, permissions, and more. Unlike wildcards, which only match in the current directory, find descends recursively into every subdirectory of the path you specify.
# Find all .log files under /var/log
find /var/log -name "*.log"
# Find files modified in the last 24 hours
find /etc -mtime -1
# Find files larger than 100MB
find / -size +100M
# Find all directories named "cache"
find / -type d -name "cache"
# Find files owned by a specific user
find /home -user alice
# Find and delete all .tmp files (use with caution)
find /tmp -name "*.tmp" -delete
# Find files with specific permissions
find /etc -perm 644# find /var/log -name "*.log" /var/log/auth.log /var/log/syslog.log /var/log/kern.log /var/log/dpkg.log /var/log/apt/history.log /var/log/nginx/access.log /var/log/nginx/error.log
What just happened? find walked the entire /var/log directory tree recursively and printed every file whose name matched the *.log pattern, including files inside subdirectories like /var/log/nginx/.
Match by filename. Case-sensitive. Use -iname for case-insensitive matching.
f for regular files, d for directories, l for symbolic links.
-1 means modified within 1 day. +7 means older than 7 days.
Run a command on each result. The {} placeholder represents each found file. End with \;
# Use -exec to run a command on every result
# This changes ownership of every file found under /var/www
find /var/www -type f -exec chown www-data:www-data {} \;
# Find and compress log files older than 30 days
find /var/log -name "*.log" -mtime +30 -exec gzip {} \;Input and Output Redirection
Every Linux process has three standard data streams: stdin (standard input, stream 0), stdout (standard output, stream 1), and stderr (standard error, stream 2). By default, stdin reads from the keyboard and stdout/stderr print to the terminal. Redirection operators change where these streams flow.
Fig 1 — Every Linux process reads from stdin and writes to stdout and stderr
| Operator | Action | Example |
|---|---|---|
> |
Redirect stdout to file (overwrites) | ls -la > listing.txt |
>> |
Redirect stdout to file (appends) | echo "done" >> log.txt |
< |
Redirect file content as stdin | sort < names.txt |
2> |
Redirect stderr to file | find / -name x 2> err.txt |
2>&1 |
Merge stderr into stdout | cmd > all.log 2>&1 |
> /dev/null |
Discard output entirely | cmd > /dev/null 2>&1 |
# Save directory listing to a file (overwrite)
ls -la /etc > /tmp/etc_listing.txt
# Append today's date to a log file
date >> /var/log/myscript.log
# Save only errors from a long-running command
find / -name "*.conf" 2> /tmp/find_errors.txt
# Save both stdout and stderr to the same file
apt upgrade > /tmp/upgrade.log 2>&1
# Run a noisy cron job silently
/opt/scripts/cleanup.sh > /dev/null 2>&1Pipes
A pipe (|) connects the stdout of one command directly to the stdin of the next. This lets administrators chain small, focused commands together into powerful one-liners without creating intermediate files.
Fig 2 — Each command's output becomes the next command's input
# Count how many lines in /etc/passwd contain the word "bash"
grep "bash" /etc/passwd | wc -l
# List the 10 largest files in /var/log
ls -lhS /var/log | head -10
# Show unique failed login attempts from the auth log
grep "Failed password" /var/log/auth.log | awk '{print $11}' | sort | uniq -c | sort -rn
# Find all running processes containing "nginx" and count them
ps aux | grep nginx | grep -v grep | wc -l
# View /etc/passwd sorted alphabetically and paged
cat /etc/passwd | sort | less# grep "Failed password" ... | sort | uniq -c | sort -rn
47 192.168.1.105
31 10.0.0.22
18 203.0.113.44
9 198.51.100.7
What just happened? Four commands were chained together. grep extracted failed login lines, awk pulled out the IP address field, sort | uniq -c counted occurrences per IP, and the final sort -rn ranked them highest first — revealing the top brute-force attackers in one line.
Analogy: A pipe is an assembly line. Each station (command) does one job well, then passes the work along. No single worker needs to do everything — the power comes from the combination.
Hard Links and Symbolic Links
Linux supports two types of file links created with the ln command. Both create an additional name pointing to a file, but they work in fundamentally different ways.
Hard Link
- Points directly to the inode (data on disk)
- File survives if the original name is deleted
- Cannot span different filesystems or partitions
- Cannot link to directories
- Created with:
ln file.txt hardlink
Symbolic Link (Symlink)
- Points to the path (name) of the target file
- Breaks if the target file is deleted or moved
- Can span filesystems and partitions
- Can link to directories
- Created with:
ln -s /etc/nginx nginx
# Create a hard link
ln /var/log/app.log /home/alice/app.log
# Create a symbolic link to a config directory
ln -s /etc/nginx /home/alice/nginx-config
# Create a symlink to the current version of an app
ln -s /opt/app-v2.4.1 /opt/app-current
# List symlinks — shown with -> in ls output
ls -la /opt/
# lrwxrwxrwx 1 root root 14 Mar 10 09:00 app-current -> /opt/app-v2.4.1
# Remove a symlink (do NOT use rm -r — that deletes the target)
rm /opt/app-currentUseful File Inspection Commands
A small set of additional commands rounds out everyday file work. These are frequently needed when investigating unfamiliar systems or diagnosing problems.
| Command | Purpose | Example |
|---|---|---|
file |
Identify the type of a file regardless of extension | file /bin/ls |
stat |
Display detailed inode info — size, permissions, timestamps | stat /etc/passwd |
wc |
Count lines, words, and bytes in a file | wc -l /etc/passwd |
sort |
Sort lines of text alphabetically or numerically | sort -rn sizes.txt |
uniq |
Filter or count duplicate adjacent lines (use after sort) | sort ips.txt | uniq -c |
Overwrite vs Append — A Critical Distinction
The single > operator overwrites the target file completely with no warning — even if it contains important data. Always use >> when you intend to add to an existing file. Running command > /etc/passwd by mistake would destroy the user account database instantly. Double-check the target path and operator before redirecting output on a production server.
Lesson Checklist
*, ?, and [] wildcards to match multiple files in a single command
find to locate files by name, type, size, age, and owner
> (overwrite) and >> (append) and when to use each
ln
Teacher's Note
The pipe-based failed-login analysis command in Section 4 is a real technique used in incident response. Practice building your own pipe chains — start with two commands and keep adding stages until you get exactly the output you need.
Practice Questions
1. Write a single command that finds all files under /var/log larger than 50MB and older than 7 days, then deletes them.
2. A deployment script produces a lot of output and error messages. Write the redirection that saves all stdout to /var/log/deploy.log and all stderr to /var/log/deploy_errors.log separately.
3. Explain a practical use case for a symbolic link on a production server. Include the exact ln command you would use and describe what happens to the symlink if the target directory is deleted.
Lesson Quiz
1. The glob pattern file?.txt would match which of the following filenames?
2. The redirection operator 2>&1 achieves which of the following?
3. A symbolic link differs from a hard link in that a symbolic link will do which of the following if its target file is deleted?
Up Next
Lesson 6 — File Permissions and Ownership
chmod, chown, octal notation, and the Unix permission model explained in full