Study guide
7.1 Conditional Execution: if, test, and []
Red Hat Certified System Administrator RHCSA
Track your progress as you read
Finished sections get a check mark.
1 Introduction & Exam Overview
1.1 Current Exam Facts 1.2 Lab Setup & Performance-Based Study Strategy
2 Essential Tools: Shell, Redirection & Text Analysis
2.1 Shell Prompt and Command Syntax 2.2 Input-Output Redirection and Pipes 2.3 grep and Regular Expressions for Text Analysis
3 Essential Tools: Remote Access, Users & Text Editing
3.1 Access Remote Systems Using SSH 3.2 Log In and Switch Users in Multiuser Targets 3.3 Create and Edit Text Files
4 Essential Tools: Files, Links & Archives
4.1 Create, Delete, Copy, and Move Files and Directories 4.2 Hard and Soft Links 4.3 Archive and Compress with tar, gzip, and bzip2
5 Essential Tools: Permissions & System Documentation
5.1 List, Set, and Change Standard ugo/rwx Permissions 5.2 System Documentation: man, info, and /usr/share/doc
6 Manage Software: RPM and Flatpak
6.1 Configure Access to RPM Repositories 6.2 Install and Remove RPM Software Packages 6.3 Configure Access to Flatpak Repositories 6.4 Install and Remove Flatpak Software Packages
7 Create Simple Shell Scripts
7.1 Conditional Execution: if, test, and [] 7.2 Looping Constructs for Files and Input 7.3 Process Script Inputs ($1, $2, and Beyond) 7.4 Process Shell Command Output in Scripts
8 Operate Running Systems: Boot and Recovery
8.1 Boot, Reboot, and Shut Down a System Normally 8.2 Boot Systems into Different Targets Manually 8.3 Interrupt the Boot Process to Gain Access
9 Operate Running Systems: Processes and Tuning
9.1 Identify and Kill CPU/Memory Intensive Processes 9.2 Adjust Process Scheduling 9.3 Manage Tuning Profiles
10 Operate Running Systems: Logs, Services & File Transfer
10.1 Locate and Interpret System Log Files and Journals 10.2 Preserve System Journals 10.3 Start, Stop, and Check Status of Network Services 10.4 Securely Transfer Files Between Systems
11 Configure Local Storage: Partitions and LVM
11.1 List, Create, and Delete Partitions on GPT Disks 11.2 Create and Remove Physical Volumes 11.3 Assign Physical Volumes to Volume Groups 11.4 Create and Delete Logical Volumes
12 Configure Local Storage: Mounting and Expansion
12.1 Mount File Systems at Boot by UUID or Label 12.2 Add Partitions, Logical Volumes, and Swap Non-Destructively
13 Create and Configure File Systems: Local FS and Permissions
13.1 Create, Mount, and Use VFAT, ext4, and XFS File Systems 13.2 Extend Existing Logical Volumes 13.3 Diagnose and Correct File Permission Problems
14 Create and Configure File Systems: NFS and autofs
14.1 Mount and Unmount Network File Systems Using NFS 14.2 Configure autofs
15 Deploy and Maintain: Scheduling, Services & Targets
15.1 Schedule Tasks with at, cron, and systemd Timers 15.2 Start, Stop, and Enable Services at Boot 15.3 Configure Systems to Boot into a Specific Target
16 Deploy and Maintain: Time, Software Updates & Bootloader
16.1 Configure Time Service Clients 16.2 Install and Update Software from CDN, Remote Repos, and Local Files 16.3 Modify the System Bootloader
17 Manage Basic Networking
17.1 Configure IPv4 and IPv6 Addresses 17.2 Configure Hostname Resolution 17.3 Configure Network Services to Start Automatically at Boot 17.4 Restrict Network Access Using firewalld and firewall-cmd
18 Manage Users and Groups
18.1 Create, Delete, and Modify Local User Accounts 18.2 Change Passwords and Adjust Password Aging 18.3 Create, Delete, and Modify Local Groups and Memberships 18.4 Configure Privileged Access
19 Manage Security: Firewall, umask & SSH Keys
19.1 Configure Firewall Settings with firewall-cmd and firewalld 19.2 Manage Default File Permissions 19.3 Configure Key-Based Authentication for SSH
20 Manage Security: SELinux Modes and Contexts
20.1 Set Enforcing and Permissive Modes for SELinux 20.2 List and Identify SELinux File and Process Contexts 20.3 Restore Default File Contexts
21 Manage Security: SELinux Ports and Booleans
21.1 Manage SELinux Port Labels 21.2 Use Boolean Settings to Modify SELinux Settings
7.1 Conditional Execution: if, test, and []
Key Takeaways Explain This Topic AI
A bash script needs a shebang (usually #!/bin/bash), executable permission (chmod +x), and is invoked by path (./script.sh) or by bash script.sh.
if/elif/else branches on command exit status: 0 is true/success; non-zero is false/failure—use $? to inspect status after a command.
test and [ ] are the classic condition helpers; [[ ]] is a bash conditional compound with safer string/pattern behavior—prefer what the task environment and man pages support.
Always leave spaces inside [ ... ] and quote variables: [ -f "$file" ]; bare [ -f $file ] breaks on empty values or spaces.
EX200 scripts are short and practical: check files/users/args, print messages, exit with meaningful status codes that survive grader checks.
Last updated: August 2026
7.1 Conditional Execution: if, test, and []
Quick Answer: Create a bash script with #!/bin/bash , chmod +x script.sh , then branch with if condition; then ... elif ... else ... fi . Conditions are usually test / [ ... ] (or bash [[ ... ]] ) and any command whose exit status is 0 (true) or non-zero (false). Quote variables and put spaces inside brackets.
Why scripting is an EX200 category
Official study points list Create simple shell scripts as its own skill group. Graders look for a working script on disk that:
- Runs under bash on RHEL 10
- Accepts or checks inputs as described
- Makes conditional decisions (this section)
- Often loops and processes arguments or command output (later sections)
You are not writing large applications. You are writing short, reliable automation —often 10–40 lines—that an admin would leave in /usr/local/bin or a lab path the task names.
- Anatomy of a minimal executable script #!/bin/bash
- # check-file.sh — example EX200-style script
- if [ ! -f /etc/hosts ]; then
- echo "ERROR: /etc/hosts missing" >&2
- exit 1
- fi
- echo "/etc/hosts is present"
- exit 0
- Shebang
The first line #!/bin/bash (shebang) tells the kernel which interpreter runs the file when executed directly. On RHEL 10, /bin/bash is the standard interactive and scripting shell for EX200-style work.
- Shebang When to use
- #!/bin/bash Preferred for bash features and exam scripts
- #!/usr/bin/env bash Portable labs; also fine if bash is on PATH
- #!/bin/sh POSIX sh only—avoid bash-only syntax if you use this
Exam habit: Use #!/bin/bash unless the task forces /bin/sh .
- Permissions and invocation vim /home/student/bin/check-file.sh
- chmod +x /home/student/bin/check-file.sh
- /home/student/bin/check-file.sh
# or from the script directory:
./check-file.sh
Without execute bit, ./script.sh fails with “Permission denied.” You can still run bash script.sh without +x , but many tasks say “create an executable script”— chmod +x is part of the deliverable . ls -l check-file.sh # expect -rwxr-xr-x or similar x bits
- head -1 check-file.sh # confirm shebang
- Line endings and editors
If you paste from a Windows host, ^M line endings break the shebang ( /bin/bash^M ). Fix with sed -i 's/\r$//' script.sh or rewrite in vim on the exam system. Prefer creating scripts on the RHEL host with vim / nano .
- Exit status: the currency of conditions
- Every command returns an integer status in $? : true; echo $? # 0
- false; echo $? # 1
ls /etc/passwd; echo $?
ls /no/such; echo $? # non-zero
- Status Meaning in if
- 0 Success / “true” branch
- Non-zero Failure / “false” branch
if runs a command list; success of the last command in the condition selects then vs else : if grep -q '^root:' /etc/passwd; then
- echo "root account line exists"
- else
- echo "unexpected: no root line"
- fi
grep -q is silent and exits 0 on match—ideal for scripts.
- Set your own status for callers and graders: exit 0 # success
- exit 1 # general failure
- exit 2 # often “usage error” by convention
- if / elif / else / fi syntax #!/bin/bash
- USER_NAME="$1"
- if [ -z "$USER_NAME" ]; then
- echo "Usage: $0 username" >&2
- exit 2
- elif id "$USER_NAME" &>/dev/null; then
- echo "User $USER_NAME exists"
- exit 0
- else
- echo "User $USER_NAME does not exist"
- exit 1
- fi
Rules that cost points when broken:
then is required after the condition (same line after ; or on the next line).
fi closes every if (not end or } ).
elif chains alternatives; only one branch runs.
Redirect errors with >&2 so messages do not pollute stdout you might pipe later.
- One-liners with && and || [ -d /backup ] && echo "backup dir ok" || echo "missing backup dir"
- id alice &>/dev/null || useradd alice
Useful for tiny checks; for multi-step logic, prefer full if blocks for readability under exam stress.
test and [ ] — the classic conditionals
test EXPR and [ EXPR ] are equivalent interfaces to the same idea (on bash, [ is a builtin). Spaces are mandatory after [ and before ] : # CORRECT
if [ -f /etc/hosts ]; then echo yes; fi
- # WRONG — missing spaces
- if [-f /etc/hosts]; then echo yes; fi
- File tests you must memorize
- Expression True when
- e PATH Path exists (any type)
- f PATH Regular file
- d PATH Directory
- L PATH / -h PATH Symbolic link
- r PATH Readable by effective UID
- w PATH Writable
- x PATH Executable
- s PATH Exists and size > 0
- nt / -ot Newer than / older than (two paths) if [ -d /var/www/html ] && [ -w /var/www/html ]; then
- echo "web root is a writable directory"
- fi
- String tests
- Expression True when
- z STR String length is zero
- n STR String length is non-zero
- STR1 = STR2 Equal (POSIX; bash also accepts == inside [ on many systems)
- STR1 != STR2 Not equal if [ -z "$1" ]; then
- echo "missing argument" >&2
- exit 2
- fi
- if [ "$MODE" = "enforce" ]; then
- echo "enforcing path"
- fi
Always quote "$1" , "$file" , "$MODE" . Unquoted empty variables become missing arguments and break [ with “unary operator expected.”
Integer comparisons (use correctly)
Inside [ ] , use integer operators , not < > alone (those are redirection):
- Operator Meaning
- eq equal
- ne not equal
- lt less than
- le less or equal
- gt greater than
- ge greater or equal COUNT=$(wc -l < /etc/passwd)
- if [ "$COUNT" -gt 50 ]; then
- echo "many local users: $COUNT"
- fi
- [[ ]] — bash conditional compound
- Bash also provides [[ ... ]] (not POSIX /bin/sh ): if [[ $name == admin* ]]; then
- echo "admin-like name"
- fi
- if [[ -f $config && -r $config ]]; then
- echo "config readable"
- fi
Advantages often cited:
- Safer handling of empty strings (still quote habitually)
- && / || inside one [[ ]]
- Pattern matching with == and =~ regex (bash)
On EX200, both [ and [[ are acceptable if the script runs under #!/bin/bash . Prefer [ if you want maximum “boring admin script” portability; use [[ when patterns simplify the task. Do not mix up closing: ]] not ] .
Combining logic # AND: both must succeed
if [ -f "$file" ] && [ -r "$file" ]; then ...
# OR: either succeeds
if [ "$user" = root ] || [ "$user" = admin ]; then ...
- # Negation
- if [ ! -d /mnt/data ]; then
- mkdir -p /mnt/data
- fi
! negates a test. Parentheses for grouping in [ need careful escaping; keep conditions simple on the exam.
- Exam-style script patterns
- Pattern A: Validate argument then act #!/bin/bash
- TARGET="$1"
- if [ $# -ne 1 ]; then
- echo "Usage: $0 directory" >&2
- exit 2
- fi
- if [ ! -d "$TARGET" ]; then
- echo "Not a directory: $TARGET" >&2
- exit 1
- fi
- echo "OK: $TARGET"
- exit 0
$# is argument count (deep dive in Section 7.3). Using it in conditionals is standard.
- Pattern B: Branch on service or package presence #!/bin/bash
- if rpm -q httpd &>/dev/null; then
- echo "httpd installed"
- else
- echo "httpd missing"
- exit 1
- fi
- Pattern C: Numeric threshold from a command #!/bin/bash
- LOAD=$(cut -d. -f1 /proc/loadavg)
- if [ "$LOAD" -ge 4 ]; then
- echo "high load: $LOAD" >&2
- exit 1
- else
- echo "load ok: $LOAD"
- fi
- (Command substitution $() is covered fully in Section 7.4; you already need it for real scripts.)
- Debugging conditionals quickly bash -n script.sh # syntax check only
- bash -x script.sh # trace execution
bash -n catches missing fi / then before you waste time. bash -x shows each expanded command—gold when a condition never matches.
Common traps
[ -f $file ] without quotes when $file is empty or has spaces.
Using = vs -eq wrong — strings vs integers.
Writing if [ $a > $b ] — > redirects; use -gt .
Forgetting fi — script fails parse.
Shebang wrong or missing chmod +x when the grader runs ./name .
Assuming non-zero always means “false file test” — any command can fail for other reasons; read stderr.
Editing with DOS CRLF — breaks shebang.
Relationship to later scripting sections
Conditionals alone do not loop over files or parse many arguments. Sections 7.2–7.4 add for / while , positional parameters, and command-output processing. Together they match the four official “simple shell scripts” study points.
Section checkpoint
You should write a #!/bin/bash script, mark it executable, branch with if / elif / else / fi , build file/string/integer tests with test or [ ] (and optionally [[ ]] ), treat exit status 0 as success, emit clear errors on stderr, and exit with useful codes. That is conditional execution for EX200.