Objectives
What the exam tests
- Use standard bash script components including shebang, comments, and exit codes
- Use variables, including positional parameters and special variables
- Use conditional structures:
if/then/else/fiandcase - Use loop structures:
for,while, anduntil - Process script output using command substitution and piping
- Use test conditions for files, strings, and integers
- Make scripts executable and run them correctly
RHCSA scripts are intentionally short — typically 10–30 lines. The exam tests whether you can write a working script under time pressure, not whether you can write elegant code.
Coverage weight by topic
Script basics
Script structure and the shebang
| Element | Purpose |
|---|---|
#!/bin/bash | Shebang — tells the kernel which interpreter to use. Must be the very first line. |
# comment | Anything after # is ignored by bash (except the shebang on line 1). |
exit 0 | Exit with code 0 (success). Any non-zero value signals failure. |
On the exam, #!/bin/bash is the correct shebang. #!/bin/sh is valid but less feature-rich — avoid it unless explicitly required.
Making scripts executable and running them
A script without execute permission will fail with Permission denied when run as ./script.sh. Always chmod +x after creating a script.
Exit codes
| Code | Meaning |
|---|---|
0 | Success |
1 | General error |
2 | Misuse of shell built-in or no such file |
126 | Command found but not executable |
127 | Command not found |
128+n | Fatal signal n received (e.g., 130 = Ctrl+C) |
Input and output
Variables and parameters
Variables — declaring and using
No spaces around = when assigning. name = "Alice" is a syntax error — bash interprets name as a command.
Positional parameters
| Variable | Value |
|---|---|
$0 | Name of the script itself |
$1 … $9 | First through ninth positional argument |
${10} | Tenth argument and beyond (braces required) |
$# | Number of positional arguments passed |
$@ | All arguments as separate quoted words |
$* | All arguments as a single word |
$? | Exit status of the most recently executed command |
$$ | PID of the current shell / script |
$! | PID of the most recently backgrounded process |
Command substitution
Always prefer $(command) over backticks. It is clearer, nestable, and doesn't require escaping backslashes inside.
Variable expansion tricks
Conditionals
if / then / else / elif / fi
Spaces inside [ ] are mandatory. [$var -eq 0] is a syntax error — it must be [ $var -eq 0 ].
Test expressions — file, string, integer
File tests
-e file— exists (any type)-f file— is a regular file-d dir— is a directory-r file— readable-w file— writable-x file— executable-s file— size > 0 (not empty)-L file— is a symbolic link
String tests
-z str— string is empty (zero length)-n str— string is non-emptystr1 == str2— strings are equalstr1 != str2— strings differstr1 < str2— alphabetically lessstr1 > str2— alphabetically greater
Integer comparisons
-eq — equal to-ne — not equal to-lt — less than
-le — less than or equal-gt — greater than-ge — greater than or equal
Compound conditions and logical operators
case statement
Each pattern ends with ), the block ends with ;;, and the whole construct closes with esac. The *) pattern is a catch-all default.
Loops
for loop — iterating over a list
while loop — condition-based iteration
The while read line; do … done < file pattern is one of the most practical scripts on the RHCSA exam — know it cold.
until loop and loop control
Arithmetic in bash
Full script examples
>&2) and exits with meaningful codes — a pattern directly tested on the RHCSA.${1:-/etc}), validates input, creates directories as needed, and chains commands with && and || for inline success/failure handling.while read file processing, user existence checking with id, conditional creation, and proper error handling. A complete, exam-ready user provisioning script.systemctl is-active --quiet for clean status checks, counts failures, and exits with the failure count as the exit code — allowing the script result to be used in automation.df output through awk and into a while read loop. Shows variable parameter expansion (${usage%%%} strips a trailing %).Cheat sheet
Most-tested constructs — quick reference
#!/bin/bashchmod +x script.shbash -x script.shbash -n script.shname="value"echo "$name"val=$(command)result=$(( a + b ))$#"$@"$?${var:-default}[ -f "$file" ][ -d "$dir" ][ -z "$str" ][ $a -eq $b ][ $a -gt $b ]while read l; do … done < ffor i in {1..10}; doexit 0exit 1echo "err" >&2cmd >/dev/null 2>&1cmd1 && cmd2cmd1 || cmd2read -p "Prompt: " varTest flag quick-reference
| Flag | Type | True when… |
|---|---|---|
-e | file | Path exists (file, dir, symlink, etc.) |
-f | file | Path exists and is a regular file |
-d | file | Path exists and is a directory |
-r | file | File is readable by current user |
-w | file | File is writable by current user |
-x | file | File is executable by current user |
-s | file | File exists and has size greater than zero |
-z | string | String has zero length (is empty) |
-n | string | String has non-zero length (is not empty) |
-eq | integer | Integer a equals integer b |
-ne | integer | Integer a does not equal integer b |
-lt | integer | Integer a is less than integer b |
-le | integer | Integer a is less than or equal to b |
-gt | integer | Integer a is greater than integer b |
-ge | integer | Integer a is greater than or equal to b |
Practice quiz
Question 1 of 7
A script runs without errors but prints nothing. You want to trace exactly which commands execute and with what values. Which command should you use?
bash -x (xtrace) prints each command with expanded values before executing it — invaluable for debugging logic. -n only checks syntax without running. -v prints each line before processing (before expansion). -e causes the script to exit on any error.Question 2 of 7
Which line contains a syntax error?
=. Bash interprets name as a command and = and "Alice" as its arguments — resulting in a "command not found" error. Variable assignment in bash requires no spaces: name="Alice".Question 3 of 7
A script is called as ./backup.sh /data /tmp. Inside the script, what does $# evaluate to?
$# is the count of positional arguments — not including $0 (the script name). Two arguments were passed (/data and /tmp), so $# is 2. The script name is $0, first arg is $1, second is $2.Question 4 of 7
You want to loop through every line in /etc/hosts and print each one. Which construct is correct?
while read line; do … done < /etc/hosts is the correct pattern for line-by-line file processing. Option A passes the filename as a single word. Option D uses $(cat) which word-splits on spaces too, breaking lines with spaces. Option C has invalid until read syntax.Question 5 of 7
Which test expression checks that the variable $dir refers to an existing directory?
-d is true only if the path exists and is a directory. -f tests for a regular file (false for directories). -e tests for existence of any type. -x tests executability (also true for directories that are traversable, but that's not the right semantic here).Question 6 of 7
What is the output of this snippet?count=5; if [ $count -gt 3 ] && [ $count -lt 10 ]; then echo "yes"; else echo "no"; fi
count is 5. The test 5 -gt 3 is true AND 5 -lt 10 is true, so both conditions pass and the then branch executes, printing yes.Question 7 of 7
Which shebang line correctly declares a bash script and must appear on line 1?
#! followed immediately by the interpreter path — no space between # and !. It must be the very first line of the file with no blank lines or spaces before it. Option A has a space inside the shebang making it a comment, not a directive.