Whether you're new to Bash or have been scripting for years, preparing for a tech interview can be nerve-wracking. What if they ask something simple that you know inside out, but your mind suddenly goes blank?
That’s exactly why preparation is key, and in this guide, we’ll cover a range of essential Bash interview questions. From the basics of what it is and how it works (would hate to get those wrong!) to more advanced topics and insights into the latest updates and changes in Bash to ensure you’re not just prepared but ahead of the curve.
This way, you can go into that interview with confidence that you’ll knock it out of the park.
So grab a coffee and a notepad, and let’s see how many you can answer correctly…
Sidenote: If you find that you’re struggling with the questions in this guide, or perhaps feel that you could use some more training, or simply want to build some more impressive projects for your portfolio, then check out my complete BASH course:
You'll learn Shell Scripting fundamentals, master the command line, and get the practice and experience you need to go from beginner to being able to get hired as a DevOps Engineer, SysAdmin, or Network Engineer!
I guarantee that this is the most comprehensive and up-to-date online resource for learning Bash Scripting.
With that out of the way, let’s get into the questions.
Beginner Bash Interview Questions
#1. What is Bash?
Bash (Bourne Again SHell) is a command processor and scripting language that runs in a text-based terminal. You type commands, and it executes them.
It's been the default shell on most Linux distributions and macOS for decades, which is why it's so common in DevOps and sysadmin work. If you're managing servers, automating deployments, or writing CI/CD pipelines, you're almost certainly writing Bash.
It's built on the original Bourne Shell from the 1970s but adds a lot on top, things like command history, tab completion, arrays, and much more expressive scripting capabilities.
#2. What are BASH scripts, and how would you create and execute one of them?
As I mentioned in the last question, a Bash script is just a text file containing a list of commands that Bash runs in order. It's a basic method of automation, so that instead of typing the same commands manually every time, you write them once in a file and execute them whenever you need them.
For example
Let's say that we wanted to run a script that always typed the same message. In this case, Hello World.
#!/bin/bash
echo "Hello, World!"Easy enough right?
So let's break down this code. The first part at the top here, #!/bin/bash is called a shebang. It tells the system which interpreter to use to run the file. Without it, the system might not know to treat it as a Bash script.
Now obviously you wouldn't want to rewrite the code each time, otherwise that would defeat the purpose, so you need to save it first with a .sh extension, like script.sh. Then make it executable:
chmod +x script.shNow you can run it:
./script.shThe ./ tells the terminal to look for the script in the current directory. Run it and you'll see Hello, World! printed to the terminal.
#3. How do you define and use variables in Bash?
Variables are how you store and reuse data in a Bash script. Instead of hardcoding the same value in multiple places, you define it once and reference it throughout.
You can define a variable by assigning a value to a name without any spaces around the = sign:
name="John"
echo "Hello, $name"That'll output Hello, John. The $ is how you tell Bash you want the value of the variable rather than the literal word "name".
A few things worth knowing for the interview. Variable names are case-sensitive, so name and NAME are two different variables. And by convention, environment variables like PATH and HOME are uppercase, while variables you define in your own scripts are typically lowercase.
You can also make a variable read-only so it can't be changed later:
readonly name="John"And to remove a variable entirely, you can use:
unset name#4. What are positional parameters in Bash?
Positional parameters are how you pass arguments into a script from the command line, making it flexible enough to work with different inputs without having to modify the script itself.
You reference them using a $ followed by a number, so $1 is the first argument, $2 is the second, and so on. However, $0 is slightly different in that it's always the name of the script itself.
For example
#!/bin/bash
echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"This means that if you run this with ./script.sh hello world, you'll get:
Script name: ./script.sh
First argument: hello
Second argument: worldA couple of other useful ones to know.
$# gives you the total number of arguments passed, and $@ gives you all of them at once, which is handy when you want to loop over every argument.
For example
for arg in "$@"; do
echo "$arg"
doneAnd if you want to be safe about it, always quote ``
#5. How do you use loops in Bash?
Loops let you repeat a set of commands multiple times without having to write them out over and over. Bash has three types, and each one suits a slightly different situation.
For Loop
The For loop iterates over a list of items and runs the same commands for each one. Use this when you know exactly what you're iterating over.
For example
for i in 1 2 3; do
echo "Number: $i"
doneIn this example, the loop iterates three times, with i taking on the values 1, 2, and 3 in turn. The command echo "Number: $i" prints each value of i as the loop progresses.
This type of loop is often used when you need to perform the same action on a known set of items, like iterating over a list of filenames.
While Loop
The While loop continues to execute as long as a specified condition is true. It's commonly used when the number of iterations is not known beforehand and depends on dynamic conditions.
For example
count=1
while [ $count -le 3 ]; do
echo "Count: $count"
((count++))
doneHere, the loop starts with count set to 1 and continues running as long as count is less than or equal to 3. During each iteration, count is printed and then incremented by 1.
This loop is useful for scenarios where you need to continue looping until a certain condition changes, such as waiting for user input or processing data until a threshold is met.
Until Loop
The Until loop is similar to the While loop, but with a reversed condition: it runs until the specified condition becomes true. This is useful when you want to keep executing commands until an event occurs.
For example
until [ condition ]; do
# Commands to execute
doneThe Until loop will execute the commands inside it repeatedly until the condition specified becomes true.
This loop is particularly useful when you're waiting for something to happen, like a process to finish or a file to be created, and you want to keep checking until that condition is met.
#6. How do you perform arithmetic operations in Bash?
This one comes up because a lot of people assume Bash handles numbers the same way other languages do, and then get caught out when it doesn't behave as expected.
The main method you'll use is double parentheses (( )). You wrap your calculation inside it and assign it to a variable:
result=$((5 + 3))
echo "Result: $result"You can use +, -, *, and / inside it, as well as % for finding the remainder of a division.
However, it's important to remember that Bash only does integer arithmetic natively, so if you divide 7 by 2, you'll get 3, not 3.5. If you need decimals, you'll need to use bc:
echo "7 / 2" | bc -lYou'll also see let and expr in older scripts that do the same job, but (( )) is the modern standard.
Intermediate Bash Interview Questions
#7. What are arrays in Bash, and how do you use them?
Arrays are a way to store multiple values within a single variable, allowing you to manage lists of items like filenames, user inputs, or configuration settings efficiently.
Bash supports indexed arrays, where each element is associated with a numeric index starting from 0.
To define an array, you can list the elements inside parentheses, separated by spaces:
fruits=("Apple" "Banana" "Cherry").
Here, fruits is an array containing three elements: "Apple", "Banana", and "Cherry". You can access individual elements by referencing their index: echo ${fruits[0]} # Outputs: Apple.
This command retrieves the first element of the fruits array, which is "Apple".
You can also loop through all the elements in an array using a For loop, which is particularly useful when you need to process or display each item:
for fruit in "${fruits[@]}"; do
echo $fruit
doneIn this loop, "${fruits[@]}" represents all the elements in the fruits array, and the loop will print each fruit on a new line.
#8. How do you handle errors in Bash scripts?
One common way to handle errors is by using exit statuses, where a command returns 0 on success and a non-zero value on failure.
You can check this exit status using $? and take action based on the result:
command1
if [ $? -ne 0 ]; then
echo "command1 failed"
exit 1
fiIf command1 fails, this script prints an error message and exits with a status of 1.
Another effective method is the set -e option, which automatically exits the script if any command returns a non-zero exit status. This ensures the script stops immediately when an error occurs:
#!/bin/bash
set -e
command1
command2Here, if command1 fails, the script exits before running command2. However, set -e can be too strict in cases where you expect certain commands might fail and want to handle those failures without stopping the script.
To bypass this, you can use || true to selectively ignore errors: command3 || true. This allows command3 to fail without causing the script to exit.
These techniques help you control how errors are handled, allowing your script to respond appropriately and avoid unexpected behavior.
#9. What are set -u and set -o pipefail in Bash?
These are two options you should be adding to almost every script you write, and interviewers love asking about them because a lot of people only know about set -e and miss these entirely.
set -u treats any unset variable as an error. Without it, if you reference a variable that was never defined, Bash just substitutes an empty string, which can cause all kinds of hard-to-debug problems:
set -u
echo $undefined_variable # Script exits with error instead of printing nothingset -o pipefail makes pipelines fail correctly. Normally in Bash, a pipeline only returns the exit status of the last command. So if an earlier command in the pipe fails, you'd never know:
set -o pipefail
cat nonexistent_file.txt | grep "pattern" # Now correctly fails if cat failsWithout pipefail, that would return 0 (success) because grep succeeded, even though cat failed.
In practice you'll often see all three combined at the top of a script like so:
#!/bin/bash
set -euo pipefailThat line makes your scripts dramatically more reliable by catching errors that would otherwise slip through silently.
#10. How do you use functions in Bash?
Functions in Bash allow you to group commands into a reusable block, making your scripts more modular and easier to manage.
They also help to encapsulate specific tasks, so you can call the same set of commands multiple times without repeating code.
For example
To define a function, you simply give it a name followed by a set of parentheses and then enclose the commands in curly braces:
#!/bin/bash
greet() {
echo "Hello, $1"
}In this example, the function greet is defined to take one argument, $1, which represents the first parameter passed to the function. While the echo command inside the function prints a greeting message using this argument.
You can call the function by using its name and passing any required arguments: greet "World"
When you run this script, it will output: Hello, World.
Functions are particularly useful for encapsulating repetitive tasks or complex logic, making your scripts more organized and easier to maintain.
By breaking down your script into smaller, reusable functions, you can improve readability and make updates or changes with less effort.
#11. What is the difference between source and ./ when executing a script?
The source (or its shorthand .) command runs a script within the current shell environment, meaning any changes to variables, functions, or the environment persist after the script finishes.
For example
source script.sh
# or
. script.shOn the other hand, ./ runs the script in a new subshell, which is a separate process. Any changes made by the script do not affect the current shell environment: ./script.sh.
Use source when you need the script to modify the current shell environment, and use ./ when you want to run the script in isolation.
#12. How do you use conditional statements in Bash?
Conditional statements let you control what your script does based on whether certain conditions are true or false.
For example
The if/elif/else structure is the most common. You use it when you need to check a condition and branch based on the result:
if [ $value -gt 10 ]; then
echo "Greater than 10"
elif [ $value -eq 10 ]; then
echo "Equal to 10"
else
echo "Less than 10"
fiHowever, the case statement is cleaner when you're checking a single variable against multiple possible values, similar to a switch statement in other languages:
case $variable in
pattern1)
echo "Pattern 1 matched"
;;
pattern2)
echo "Pattern 2 matched"
;;
*)
echo "No pattern matched"
;;
esacThese structures allow you to perform different actions depending on the outcomes of conditions, making your script more dynamic and adaptable. It's worth pointing out that the *) at the end is the catch-all, like an else, so if nothing else matches, that's what runs.
#13. How do you use grep in Bash?
grep is a command-line utility used to search for patterns in files. It’s highly versatile and can be used in various ways. It searches for patterns in files or output, which makes it invaluable for things like parsing logs, finding config values, or filtering command output.
The basic syntax is straightforward.
For example
To search for a pattern in a file you can use grep "error" /var/log/syslog. That'll print every line in the file that contains the word "error".
With that in mind, here are a few flags that are worth knowing:
-i makes the search case-insensitive like so, grep -i "error" /var/log/syslog.
While -r searches recursively through a directory grep using -r "error" /var/log/.
Then you have -c which gives you a count of matching lines rather than the lines themselves like so: grep -c "error" /var/log/syslog.
And finally, we have -v which inverts the search, and returns lines that don't match like so grep -v "error" /var/log/syslog.
However, where grep really becomes powerful is when you combine it with other commands using pipes. For example, to find a running process like ps aux | grep nginx, or to search through command output in real time with tail -f /var/log/syslog | grep "error".
That last one is particularly useful in production when you're monitoring logs and only want to see the lines that matter.
#14. How do you use awk and sed in Bash?
These two tools come up constantly in Bash interviews because they're the go-to options for text processing on the command line. They're often used together with grep, so it's worth knowing how they differ.
sed (Stream Editor) is best for find-and-replace operations and simple text transformations. The most common use is substituting text:
sed 's/old/new/' file.txtThat replaces the first occurrence of "old" with "new" on each line. To replace all occurrences on every line, add the g flag:
sed 's/old/new/g' file.txtYou can also use sed to delete lines matching a pattern:
sed '/pattern/d' file.txtOr to edit a file in place rather than just printing the output:
sed -i 's/old/new/g' file.txtawk is more powerful and is better suited for working with structured data, like CSV files or log files with consistent columns. It processes files line by line and lets you reference individual fields:
awk '{print $1}' file.txtThat prints the first field of every line. By default, awk splits on whitespace, but you can specify a different delimiter:
awk -F',' '{print $2}' file.csvThat prints the second column of a comma-separated file. You can also add conditions:
awk '$3 > 100 {print $1, $3}' file.txtThat prints columns 1 and 3 for any line where column 3 is greater than 100.
The short version for your interview answer: reach for sed when you need to find and replace or transform text, and reach for awk when you need to work with structured columns or apply logic to specific fields.
#15. How do you use xargs in Bash?
xargs takes the output of one command and passes it as arguments to another. The reason you need it is that some commands don't accept piped input directly.
For example
echo and rm expect arguments, not stdin, so if you try to pipe a list of files to rm, it won't work. The good news is we can use xargs to bridge that gap:
find /tmp -type f -name "*.log" | xargs rmThat finds all .log files in /tmp and deletes them, which is handy because without xargs you would have to loop through them manually.
Another common use is running a command on multiple items in parallel with the -P flag:
cat urls.txt | xargs -P 4 -I {} curl {}That runs 4 curl requests simultaneously, one for each URL in the file. The -I {} tells xargs where to substitute each item.
One thing to watch out for: If your filenames contain spaces, use ``-0`` with ``xargs`` and ``-print0`` with ``find`` to handle them safely:
find /tmp -type f -name "*.log" -print0 | xargs -0 rm^^ That's the safe, production-ready version you'd want to mention in an interview.
#16. How do you schedule tasks using cron?
cron is a job scheduler that lets you run scripts or commands automatically at specified times or intervals. It's how you automate things like nightly backups, log rotation, or sending reports without having to remember to run them manually.
Each cron job is defined by a single line with five time fields followed by the command you want to run.
The five fields are:
* * * * * /path/to/script.sh
# │ │ │ │ │
# │ │ │ │ └── Day of the week (0-7, where 0 and 7 are Sunday)
# │ │ │ └──── Month (1-12)
# │ │ └────── Day of the month (1-31)
# │ └──────── Hour (0-23)
# └────────── Minute (0-59)So let's break this down. A * in any field means "every", so five *s means "run every minute of every hour of every day".
For example, to run a script every day at 5:00 AM:
0 5 * * * /path/to/script.shAnd if we wanted to run it every Monday at 9:00 AM we would use:
0 9 * * 1 /path/to/script.shTo edit your cron jobs, use:
crontab -eAnd to list your current cron jobs:
crontab -lTop tip: If you're ever unsure about a cron expression, crontab.guru is a handy tool that lets you paste in an expression and see exactly when it will run in plain English.
#17. How do you handle command-line arguments in Bash scripts?
Command-line arguments allow you to pass input to your script, making it more dynamic.
And the simplest way to access these arguments is through positional parameters like $1, $2, etc.
For example
#!/bin/bash
echo "Script name: $0"
echo "First argument: $1"
echo "Second argument: $2"For more complex argument handling, you can use getopts to process options:
while getopts ":a:b:" opt; do
case $opt in
a) echo "Option A with value: $OPTARG" ;;
b) echo "Option B with value: $OPTARG" ;;
\?) echo "Invalid option: -$OPTARG" ;;
esac
doneThis allows you to create scripts that accept flags and options, similar to many command-line utilities.
Advanced Bash Interview Questions
#18. What is the significance of the trap command in Bash?
The trap command is used to catch and handle signals, allowing you to define actions that should be taken when a script receives a signal like SIGINT (Ctrl+C).
This is crucial for ensuring that your script can perform cleanup tasks or execute critical code even when interrupted.
For example
To catch the SIGINT signal, you could use:
If you press Ctrl+C while this script is running, it will print "Script interrupted" and exit gracefully.
You can also use trap to handle multiple signals or more complex tasks.
For example
Handling the EXIT signal ensures that a specific command runs whenever the script exits, regardless of the exit status: trap "echo 'Cleaning up...'; rm -f /tmp/tempfile" EXIT
This trap command removes a temporary file when the script finishes, whether it completes successfully or is interrupted.
trap is also useful for managing signals like HUP (hangup) to restart services or reload configurations.
#19. How do you use process substitution in Bash?
Process substitution is a powerful tool for advanced data processing, allowing you to streamline complex command chains and manage data more flexibly in your scripts.
It also allows you to use the output of a command as if it were a file, making it possible to pass data between commands that expect file inputs. This feature is particularly useful for comparing command outputs or chaining commands together.
There are two main forms of process substitution:
Input Substitution (`<(...)`)
The output of the command inside (...) is treated as a file, which can be read by another command.
For example
If we wanted to compare the contents of two directories: diff <(ls dir1) <(ls dir2).
Here, ls dir1 and ls dir2 are executed in subshells, and their outputs are compared by diff as if they were files.
Output Substitution (`>(...)`)
The command inside (...) writes its output to a file-like object, which can be read by another command.
For example
You can redirect the output of a command into another process: tee >(gzip > output.gz) < input.txt.
In this example, tee writes the contents of input.txt to both the standard output and a gzip-compressed file output.gz.
#20. What is the purpose of exec in Bash?
The exec command in Bash replaces the current shell process with a specified command, meaning the shell stops running, and the command takes over completely.
This is useful for improving performance by avoiding the overhead of creating a new process.
For example
#!/bin/bash
exec ls -l
echo "This will not be printed"In this script, exec ls -l replaces the shell, so the echo command never executes.
exec is also powerful for manipulating file descriptors, as it allows you to redirect input/output streams, which is particularly useful for managing how a script interacts with files or other processes.
For example
You can redirect standard output to a file throughout the script:
exec > output.log
echo "This will be logged in output.log"
exec < input.txt
cat # This will read from input.txtBy using exec to manage file descriptors, you can fine-tune how your scripts handle input and output, making them more efficient and flexible.
#21. What is a subshell? How do you use subshells in Bash?
A subshell is a child process created by the parent shell to execute commands in a separate environment.
Commands enclosed in parentheses () are executed in a subshell, meaning any changes to the environment (like variables or the working directory) are isolated from the parent shell.
For example
If you want to temporarily change the working directory and execute some commands without affecting the main shell:
(
cd /new/directory
echo "Current directory in subshell: $(pwd)"
)
echo "Current directory in parent shell: $(pwd)"Here, the cd command only changes the directory within the subshell, and the parent shell remains unaffected.
Subshells are also useful for running commands in parallel, which can improve the efficiency of your scripts:
(
sleep 2
echo "Task 1 completed"
) &(
sleep 1
echo "Task 2 completed"
) &
waitThis allows multiple tasks to run concurrently, which is particularly useful in scripts that perform time-consuming operations.
#22. How do you manage background processes in Bash?
You can manage background processes in Bash to run tasks concurrently without blocking the terminal. To start a process in the background, append an & to the command:
./long_running_script.sh &.
If you need to bring a background process to the foreground, use fg like so: fg %1.
To see all background jobs, use jobs.
You can also terminate a specific job with kill and then the job name kill %1.
In addition to managing background jobs, you can use disown to detach a job from the terminal, allowing it to continue running even if the terminal is closed:
./long_running_script.sh &
disown %1You can also run multiple commands simultaneously in the background, which is useful for multitasking:
command1 &
command2 &
waitThis way, you can perform several tasks in parallel while still using the terminal for other commands.
#23. What are Here Documents (heredocs) in Bash?
A heredoc lets you pass a block of text to a command directly within your script, without needing a separate file. It's particularly useful for generating config files, sending multi-line input to a command, or embedding SQL queries or HTML in a script.
The syntax uses << followed by a delimiter word, traditionally EOF, though you can use anything:
cat <<EOF
This is a
multiline string
EOFEverything between the two EOF markers is treated as input to the command. Variables are expanded inside a heredoc by default:
name="John"
cat <<EOF
Hello, $name
Today is $(date)
EOFIf you want to prevent variable expansion and treat the content as literal text, quote the delimiter:
cat <<'EOF'
Hello, $name
This will print literally, not expand the variable
EOFHeredocs are also useful for writing multi-line content to a file like so:
cat <<EOF > config.txt
host=localhost
port=5432
database=mydb
EOFOr passing multi-line input to commands like ssh to run several commands on a remote server in one go:
ssh user@server <<EOF
cd /var/www
git pull
systemctl restart nginx
EOF#24. What is command substitution in Bash?
Command substitution allows you to capture the output of a command and use it as input for another command.
This can be done using either backticks or the preferred $(command) syntax:
current_date=$(date)
echo "Today is $current_date"This captures the output of date and assigns it to current_date. Command substitution is essential for making scripts dynamic by embedding command outputs within other commands.
#25. How do you redirect output in Bash?
Output redirection in Bash allows you to control where the output of a command is sent, which is essential for managing data flow in your scripts. Common redirection operators include:
>: Redirects output to a file, overwriting it.
>>: Appends output to a file without overwriting.
2>: Redirects standard error to a file.
&>: Redirects both standard output and error to a file.
For example
You can redirect standard output to a file and errors to another file:
echo "Hello, World!" > output.txt
ls non_existent_file 2> error.logIf you want to suppress output, you can redirect it to /dev/null, effectively discarding it: command > /dev/null 2>&1. Here, both the standard output and error are redirected to /dev/null.
To combine standard output and error streams into the same file, you can use 2>&1 like so command > output.log 2>&1
This ensures that both outputs are captured in a single log file, making it easier to troubleshoot issues.
#26. What are symbolic links, and how do you create them in Bash?
A symbolic link is a file that points to another file or directory, acting like a shortcut.
You create a symbolic link using ln -s like so ln -s target_file link_name.
Symbolic links are useful for managing shared resources, organizing files, and creating easy access points in your file system.
#27. How do you check for file or directory existence in Bash?
You can check for the existence of a file or directory using conditional expressions:
if [ -f "file.txt" ]; then
echo "File exists."
else
echo "File does not exist."
fi
if [ -d "directory" ]; then
echo "Directory exists."
else
echo "Directory does not exist."
fiThis ensures your script handles files and directories appropriately, preventing errors by checking their existence first.
#28. How do you perform string manipulation in Bash?
Bash provides several built-in methods for manipulating strings, which are essential for tasks like formatting text, parsing input, and preparing data within scripts.
Extracting Substrings
You can extract a portion of a string by specifying the starting position and length. The syntax ${str:start:length} is used for this purpose:
str="Hello, World!"
echo ${str:7:5} # Output: WorldHere, the substring starting at position 7 (zero-based) with a length of 5 characters is extracted, resulting in "World".
Replacing Parts of Strings
Bash allows you to replace occurrences of a substring within a string using the ${str/old/new} syntax: echo ${str/World/Bash} # Output: Hello, Bash!
This replaces the first occurrence of "World" with "Bash". To replace all occurrences, you can use ${str//old/new}.
Changing Case
You can also convert strings to uppercase or lowercase. The syntax ${str^^} converts the entire string to uppercase, while ${str,,} converts it to lowercase:
echo ${str^^} # Output: HELLO, WORLD!
echo ${str,,} # Output: hello, world!This is particularly useful for normalizing text, ensuring consistency in data processing, and preparing strings for case-sensitive operations.
#29. What is the difference between && and || in Bash?
The && and || operators in Bash are logical operators that control the flow of commands based on the success or failure of the previous command:
&& executes the next command only if the previous one succeeds (i.e., returns an exit status of 0). While || executes the next command only if the previous one fails (i.e., returns a non-zero exit status).
For example
mkdir new_dir && cd new_dir # Change directory only if mkdir succeeds
command || echo "Command failed" # Print message if command failsThese operators allow you to create more robust scripts by chaining commands conditionally.
You can also combine && and || to create more complex logic in a single line: command && echo "Success" || echo "Failure".
In this case, if command succeeds, it prints "Success"; if it fails, it prints "Failure".
This combination can be particularly useful for concise error handling and decision-making within scripts.
#30. How do you use loops to iterate over files in a directory in Bash?
In Bash, you can use a For loop to iterate over files in a directory, allowing you to perform operations on each file.
This is particularly useful for batch processing tasks such as renaming files, converting formats, or applying the same command to multiple files.
For example
#!/bin/bash
for file in /path/to/directory/*; do
echo "Processing $file"
doneThis loop processes each file in the specified directory, while the * wildcard matches all files, but you can also use more specific patterns, like *.txt, to only process certain types of files.
If your file names contain spaces, it’s important to quote the variable to prevent issues:
for file in /path/to/directory/*; do
echo "Processing \"$file\""
doneFor more complex directory structures, you might prefer using a while loop with find to iterate over files recursively:
#!/bin/bash
find /path/to/directory -type f | while read file; do
echo "Processing $file"
doneThis approach finds all files under the specified directory and processes them, regardless of depth.
It’s particularly useful when dealing with nested directories or when you need more control over which files are processed.
#31. How do you debug a Bash script?
Debugging is something every sysadmin and DevOps Engineer needs to know how to do, and it comes up in interviews because it shows you understand what's happening inside your scripts, not just how to write them.
The most useful tool is bash -x, which runs your script in debug mode and prints each command to the terminal before executing it:
bash -x script.shThe output shows each command with a
+You can also enable debug mode from inside the script itself using set -x, which is useful if you only want to debug a specific section:
set -x # Start debug output
# commands you want to debug
set +x # Stop debug outputAnother handy option is set -v, which prints each line of the script as it's read rather than as it's executed. This is useful for catching syntax errors before they cause problems.
For more complex debugging, you can combine these with the PS4 variable to make the debug output more informative. By default, PS4 is just +, but you can change it to show the line number:
export PS4='Line ${LINENO}: '
bash -x script.shNow the debug output tells you exactly which line each command is on, which saves a lot of time in longer scripts.
How did you do?
There you have it! 31 of the most common Bash questions and answers that you might encounter in an interview for a DevOps interview using Bash.
What did you score? Did you nail all 31 questions? If so, it might be time to move from studying to actively interviewing!
Didn't get them all? Got tripped up on a few? Don't worry because I'm here to help!
If you want to fast-track your Bash knowledge and interview prep, and get as much hands-on practice as possible, then check out my complete BASH course:
Like I said earlier, you'll learn Shell Scripting fundamentals, master the command line, and get the practice and experience you need to go from beginner to being able to get hired as a DevOps Engineer, SysAdmin, or Network Engineer!
Plus, once you join, you'll have the opportunity to ask questions in our private Discord community from me, other students, and working DevOps professionals.
If you join or not, I just want to wish you the best of luck with your interview!
Best articles. Best resources. Only for ZTM subscribers.
If you enjoyed this post and want to get more like it in the future, subscribe below. By joining the ZTM community of over 100,000 developers you’ll receive Web Developer Monthly (the fastest growing monthly newsletter for developers) and other exclusive ZTM posts, opportunities and offers.
No spam ever, unsubscribe anytime
Want more Bash content?
If you enjoyed this post, then check out my other Bash guides and tutorials!






