Module 1: Essential Tools and Shell Scripts
RHCSA domains covered: Essential Tools (1), Simple Shell Scripts (2).
Lab in this kit: Implicitly exercised across all 10 labs — the graders themselves are bash scripts you'll read.
Every other domain rides on top of this one. Partitioning a disk, fixing an SELinux context, editing a service file — each is really a sequence of "find the thing, look at it, change it, redirect the output somewhere." If those base motions are slow, every task on the exam is slow. This module is the toolbox: locating files, moving text around with pipes and redirection, linking, archiving, and writing the small bash scripts that automate repetitive work. Treat the goal as *fluency without lookup* — by exam day these should be reflex, not recall.
Finding things
What it is: three different ways to locate files, each with a different trade-off.
Why it matters: half of "I can't configure X" turns out to be "I can't find X's config file." Knowing the right search tool saves minutes per task.
find /etc -name '*.conf' # search live, by name, anywhere under /etc
grep -rn 'pattern' /etc # search live, by file CONTENT (-r recursive, -n line numbers)
locate file # search a prebuilt index (fast, but run updatedb first)
find walks the filesystem in real time, so it's always current but slower on big trees — reach for it when you need to match on name, size, owner, or modification time. grep -rn searches *inside* files, which is how you find "which config has this setting." locate is instant because it queries a database, but that database is only as fresh as the last updatedb run — handy for "where did that package put its files," useless for something you created ten seconds ago.
Archiving and compression
What it is: tar bundles many files into one archive; the z/j/J flags add gzip/bzip2/xz compression.
Why it matters: the exam frequently hides archive work inside a larger task ("back up /etc to /root/etc.tar.gz"), and tar flags are easy to fumble under pressure.
tar czf backup.tar.gz /etc # create (c), gzip (z), to file (f)
tar xpf backup.tar.gz # extract (x), preserve permissions (p)
tar tzf backup.tar.gz # list contents without extracting (t)
Read the flags as a sentence: czf = "create, zipped, file-named." xpf = "extract, preserving perms, from this file." The p matters when you're restoring system files — without it, extracted files get *your* umask instead of their original modes, which quietly breaks things like /etc/shadow. The f always comes last because the filename is its argument.
Links
What it is: two ways to make a file reachable by more than one name. A *hard link* is a second directory entry pointing at the same data; a *symbolic link* is a tiny file that just stores a path to another file.
Why it matters: they behave differently when the original moves or is deleted, and the exam expects you to know which is which.
ln src dst # hard link — dst IS the same inode as src
ln -s src dst # symbolic link — dst POINTS to the path "src"
Delete the original of a *hard* link and the data survives, because both names point at the same underlying inode — the data only disappears when the last name does. Delete the original of a *symbolic* link and you're left with a dangling pointer to nothing. Hard links can't cross filesystems or point at directories; symlinks can do both. When in doubt on the exam, -s (symbolic) is almost always what's wanted.
Redirection and pipes
What it is: the shell's plumbing — sending a command's output to a file instead of the screen, or into another command.
Why it matters: this is how you capture output for grading, log results, and chain tools together. It's in nearly every scripted task.
| Goal | Syntax | |
|---|---|---|
| stdout to file (overwrite) | cmd > file | |
| stdout to file (append) | cmd >> file | |
| stderr to file | cmd 2> file | |
| both streams to one file | cmd > file 2>&1 or cmd &> file | |
| feed one command into another | `cmd1 \ | cmd2` |
The key idea: every process has three streams — stdin (0), stdout (1), stderr (2). > redirects stdout by default; 2> targets stderr specifically. 2>&1 means "send stream 2 to wherever stream 1 is currently going" — order matters, so > file 2>&1 works but 2>&1 > file doesn't. A pipe (|) wires one command's stdout into the next command's stdin, which is how ps aux | grep httpd works.
In-place editing with sed
What it is: sed is a stream editor; -i makes it edit a file in place instead of printing to the screen.
Why it matters: it's the fastest way to change a config setting non-interactively, and it scripts cleanly.
sed -i 's/^SELINUX=.*/SELINUX=enforcing/' /etc/selinux/config
The s/old/new/ is a substitution; the trailing g (when present) means "every match on the line, not just the first." Here ^SELINUX=.* anchors to the start of the line and matches the whole value, so the line is rewritten regardless of what it currently says. sed -i is the workhorse for "set this directive to this value" tasks — faster and more repeatable than opening an editor.
Man pages
What it is: the offline manual — your *only* reference during the exam.
Why it matters: no internet means man and --help are all you get. Knowing how to navigate them quickly is itself an exam skill.
man 5 passwd # section 5 = file formats (the /etc/passwd FILE, not the command)
man -k password # keyword search across all man pages (same as apropos)
cmd --help # quick flag reminder without leaving the command
The numbered sections matter: section 1 is commands, section 5 is file formats, section 8 is admin tools. man passwd gives you the *command*; man 5 passwd gives you the *file format*. When you can't remember a command's name, man -k <keyword> (or apropos) searches every page's description — that's how you rediscover semanage, firewall-cmd, and friends mid-exam.
Shell script essentials
What it is: bash scripts let you bundle a sequence of commands with logic — conditionals, loops, argument handling.
Why it matters: the "Simple Shell Scripts" objective expects you to read and write small scripts that test conditions and act on them. The patterns below cover what's actually tested.
#!/usr/bin/env bash
set -euo pipefail # exit on error, error on undefined vars, fail on pipe errors
if [ -f /etc/myapp.conf ]; then
echo "config exists"
elif [ -d /etc/myapp ]; then
echo "config dir exists"
else
echo "no config" >&2
exit 1
fi
for user in alice bob carol; do
id -u "$user" || useradd -m "$user" # create the user only if they don't exist
done
case "$1" in
start) systemctl start myapp ;;
stop) systemctl stop myapp ;;
*) echo "usage: $0 {start|stop}" >&2; exit 2 ;;
esac
The first two lines are the foundation. The shebang (#!/usr/bin/env bash) tells the kernel which interpreter to use. set -euo pipefail is the safety harness: -e stops the script the moment a command fails (instead of plowing ahead with broken state), -u treats use of an unset variable as an error (catches typos), and pipefail makes a pipeline fail if *any* stage fails, not just the last. The for loop shows a common idempotent pattern — id -u "$user" || useradd means "if the user already exists, do nothing; otherwise create them" — which matters because exam scripts may be run more than once.
File-test operators worth memorizing
These are the conditions you put inside [ ] (or [[ ]]):
| Operator | Means |
|---|---|
-e | exists (any kind) |
-f | regular file |
-d | directory |
-L | symbolic link |
-r / -w / -x | readable / writable / executable |
-s | exists and non-empty |
-z str | string is empty |
-n str | string is non-empty |
== / != | string equality (inside [[ ]]) |
-eq / -ne / -lt / -gt | numeric comparisons |
The distinction that trips people up: string comparison uses =/==, but *numeric* comparison uses -eq/-lt/-gt. [ "$x" = "5" ] tests text; [ "$x" -eq 5 ] tests numbers. Get them backwards and "10" < "9" because text sorts character by character.
Common pitfalls
for a in $*loses argument boundaries (a filename with a space splits into two). Usefor a in "$@"with the quotes to preserve them.[ "$x" = "foo" ](single=) is portable;==works only inside[[ ]]and bash'stest. The exam's/bin/shmay not be bash.- Forgetting
set -emeans a failed command silently continues and the script reports success on broken state. Start scripts with it unless you have a reason not to. - Single-quoted strings never expand variables —
'$VAR'is literally those four characters. Use double quotes when you want$VARsubstituted. - Unquoted variables (
$fileinstead of"$file") break on spaces and glob characters. Quote everything that isn't deliberately being split.
Exam tips
- Master
tarflags cold — the exam often buries archive work inside a task and you don't want to be readingman tarfor it. man -k(orapropos) is your lifeline when you blank on a command name. Practice using it so it's automatic.- Any editor is allowed (
vim,nano,emacs). Pick one and be genuinely fluent — fumbling in an unfamiliar editor wastes time you don't have. - When a task says "create a script that…", start with the shebang and
set -euo pipefailevery time. It's free insurance and graders don't penalize it.
Next: Module 2 — Operating running systems.