Quiz: Bash & Shell Mastery
Can you talk to computers? Like, well?
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!
Warmup
How are variables defined in Bash?
Variables in Bash are declared without spaces around the =
sign. For example:
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.
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:
There are other ways to handle this, but this is the most common.
Warmup: Expansion
What will this command output?
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:
Variables
Now, what will this print?
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 (\
):
Replacing Substrings
What’s happening here?
The ${var/pattern/replacement}
syntax replaces the first occurrence of pattern
with replacement
. Here, the output is:
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}
.
String Length
How can you get the length of a variable in Bash?
The ${#username}
syntax returns the length of username
.
For example:
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.
Conditionals
What does this script output if the file cats.txt
EXISTS?
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:
Note: Double brackets [[ ]]
are recommended for conditional expressions. See BashFAQ.
Conditionals
How can we compare strings in Bash?
Another Error! 🚨
Did you catch the invalid ===
operator?
You might have been thinking of JavaScript…
In Bash, use ==
for equality comparisons.
Functions
What will this script output?
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"
.
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:
Multiplication
Which of these correctly multiplies 10 and 0.5, printing 5?
String Manipulation
What does the :
do in this script?
The ${var:offset}
syntax extracts a substring starting from offset
. Here, the output is:
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 -
!)
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.
Gotchas
Which option will execute the command ls -l
and return the output?
The $(ls -l)
syntax executes the command inside the parentheses and substitutes the output. For example:
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.
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.
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: