Dan Levy's Avatar DanLevy.net

Quiz: Bash & Shell Mastery

Can you talk to computers? Like, well?

Quiz: Bash & Shell Mastery

Test your Bash scripting skills with these 16 questions!

Covering variables, loops, conditionals, string manipulation, functions and basic-to-tricky syntax gotchas.

Sharpen (or prove) your shell scripting skills!

1. 

Warmup

How are variables defined in Bash?

Variables in Bash are declared without spaces around the = sign. For example:

Terminal window
name=Alice

This assigns the value "Alice" to the variable name.

Note: $name is used to reference or read a variable’s value.

Adding spaces causes the shell to interpret the command as a program to run, which is not what you want when setting a variable.

Also, Bash is case-sensitive, so name, NAME and Name are different variables.

Finally, variables can’t have spaces or dashes (-) in their names. Use underscores (_) or camelCase instead.

2. 

Warmup: Escaping

What will print out It's 🔨 Time!?

I know. It’s wild how quickly escaping makes strings tough to parse. Imagine escaping other languages in Bash strings - with all those quotes, apostrophes and $ symbols to f*ck you up. 🫠

Single quotes need escaping inside single-quoted strings. The backslash-escaped single quote ('\'') allows output of:

It's Bash Time!

There are other ways to handle this, but this is the most common.

3. 

Warmup: Expansion

What will this command output?

Terminal window
echo c{a,b}t

The {} brace expansion generates multiple versions of its string context, one (or more) for each comma-separated value or pattern.

Here, a{b,c}d expands to:

abd acd

4. 

Variables

Now, what will this print?

Terminal window
price="$100"
echo "Cost: $price"

Numbered variables have special meaning. In this case, $1 is a special variable that holds the first argument passed to the script or function.

Since we’re running the script in a REPL, there are no arguments, so $1 is empty. The remaining text 00 is printed as-is.

To print a literal $ character, use single quotes, or escape it with a backslash (\):

Terminal window
price="\$100"
echo "Cost: $price"

5. 

Replacing Substrings

What’s happening here?

Terminal window
str="Bark bark"
echo ${str/bark/meow}

The ${var/pattern/replacement} syntax replaces the first occurrence of pattern with replacement. Here, the output is:

Bark meow

It is case-sensitive. To make it case-insensitive, use ${var^pattern/replacement}.

To replace all occurrences, use ${var//pattern/replacement}.

To replace from the beginning of the string, use ${var/#pattern/replacement}.

To replace from the end of the string, use ${var/%pattern/replacement}.

6. 

String Length

How can you get the length of a variable in Bash?

The ${#username} syntax returns the length of username.

For example:

Terminal window
username="@justsml"
echo ${#username} # => 8

While wc would work, it’s technically not a part of Bash.

The utility wc is an old inside joke referring to “water closet,” or toilet. KIDDING! Does anyone reads these?

In reality wc is an ancient command from Posix (and the AT&T Unix days.) It is short for “word count” and it can count lines, words, and characters in a file or input stream.

7. 

Conditionals

What does this script output if the file cats.txt EXISTS?

Terminal window
if [ -e cats.txt]; then
echo "File exists"
else
echo "File does not exist"
fi

Did you catch the missing space before the closing bracket?

Bash is quite touchy here: spaces are required inside bracket expressions.

The correct syntax is:

Terminal window
if [ -e example.txt ]; then
echo "File exists"
else
echo "File does not exist"
fi

Note: Double brackets [[ ]] are recommended for conditional expressions. See BashFAQ.

8. 

Conditionals

How can we compare strings in Bash?

Terminal window
cat1="Rosie"
cat2="Sunflower"
if [ "$cat1" === "$cat2" ]; then
echo "Same cat"
else
echo "Different cats"
fi

Another Error! 🚨

Did you catch the invalid === operator?

You might have been thinking of JavaScript…

In Bash, use == for equality comparisons.

9. 

Functions

What will this script output?

Terminal window
function greet () {
echo "$1"
}
greet Hi Dan

Functions in Bash can accept arguments. The $1 variable holds the first argument passed to the function.

Remember, $0 is the script name, $1 is the first argument, $2 is the second, and so on. Spaces separate arguments. So, greet Hi Dan passes "Hi" as the first argument. In order to pass "Hi Dan" as a single argument, you would need to quote it: greet "Hi Dan".

10. 

Composition

What operator connects the output of one command to the input of the next command?

The | pipe operator connects the output of one command to the input of another. For example:

Terminal window
echo "Mr. Levy 👨🏻‍🔬" | wc -m
# => 14

11. 

Arithmetic

How does math work in Bash?

The (( )) syntax performs integer math in Bash.

It can be used for simple calculations:

Terminal window
((result = 2 + 2))
echo $result # => 4

Or for conditional expressions:

Terminal window
if (( 2 > 1 )); then
echo "2 is greater than 1"
fi

For floating-point arithmetic, consider using bc or awk.

12. 

Multiplication

Which of these correctly multiplies 10 and 0.5, printing 5?

The (( )) syntax ONLY performs integer arithmetic. You know, whole numbers, with no floating point!

Bash (perhaps surprisingly) lacks built-in support for floating-point arithmetic.

The most common solution is to use GNU utils bc or awk.

13. 

String Manipulation

What does the : do in this script?

Terminal window
rosie="Bad cat, good cat"
echo ${rosie:9}

The ${var:offset} syntax extracts a substring starting from offset. Here, the output is:

good cat

To extract a substring of a specific length, use ${var:offset:length}.

To extract from the end of the string, use ${var: -offset}. (Note the space before the -!)

14. 

Loops

What is NOT ❌ a keyword for looping in Bash?

each is not a loop keyword in Bash. The main loop keywords are for, while, and until.

While do is not technically a loop keyword, it’s a key part of loop syntax.

15. 

Gotchas

Which syntax executes a ls -l while also making its output available for later use?

The $(ls -l) syntax executes the command inside the parentheses and substitutes the output. For example:

Terminal window
echo "Today is $(date +%F)"

The 1st option uses Single quotes ', not backticks. This prevents expansion, so '$(date +%F)' would simply print the literal string $(date +%F).

While it’s still supported to use backticks (`ls -l`) for command execution, it’s recently become somewhat of an anti-pattern (in some contexts.) Most recommend using $(command) for better readability & consistency with different shells & versions.

Curly braces ${} are used for variable expansion, not command substitution.

The % character is not used for command substitution.

16. 

Standard In/Out

Which operator is used to combine the error output into the standard output?

The 2>&1 operator redirects standard error (file descriptor 2) to standard output (file descriptor 1). This is useful for capturing error messages in the same output stream as regular output.

The 1>&2 operator redirects standard output to standard error, however, the question asked how to redirect standard error to standard output.

To Learn more about what’s going on under the hood, check out Greg’s excellent Redirection FAQ.

Also, thanks to Reddit user u/OneTurnMore for suggested copy improvements.

Quiz Score:

Congrats! Quiz completed.

Did my Bash Quiz leave you in shambles?

Let me know in the comments below!

Further Reading

Brush up on your Bash skills with the following resources:

Edit on GitHubGitHub