Shell Interview Questions and Answers

ShellBeginner
Practice Now

Introduction

Welcome to this comprehensive guide on Shell Interview Questions and Answers! Whether you're preparing for an interview, looking to sharpen your existing skills, or simply curious about the breadth of shell knowledge, this document is designed to be your ultimate resource. We cover everything from fundamental concepts and advanced scripting to scenario-based problem-solving and role-specific challenges, ensuring you're well-equipped for any technical discussion. Dive in to explore practical tasks, troubleshooting techniques, best practices, and essential security considerations, empowering you to confidently demonstrate your expertise in shell scripting and command-line proficiency.

SHELL

Fundamental Shell Concepts and Commands

Answer:

A hard link points directly to the inode of a file, meaning it's an additional directory entry for the same file data. A soft link (symlink) is a special file that contains a path to another file or directory. Hard links cannot span filesystems and cannot link to directories, while soft links can.


Explain the purpose of the PATH environment variable.

Answer:

The PATH environment variable is a colon-separated list of directories that the shell searches for executable commands when a command is entered without its full path. This allows users to run commands like ls or grep without specifying /bin/ls or /usr/bin/grep.


How do you redirect standard output and standard error to separate files?

Answer:

You can redirect standard output (1) and standard error (2) to separate files using command > output.txt 2> error.txt. This sends successful output to output.txt and error messages to error.txt.


What is the difference between exec and source (or .) commands?

Answer:

exec replaces the current shell process with the specified command, meaning the original shell is terminated. source (or .) executes a script in the current shell environment, meaning any variables or functions defined in the script become part of the current shell's environment.


Describe the function of the grep command and provide a basic example.

Answer:

grep (Global Regular Expression Print) is used to search for patterns in text files. It prints lines that match a given regular expression. For example, grep 'error' logfile.txt will display all lines containing the word 'error' in logfile.txt.


How do you find all files larger than 10MB in the current directory and its subdirectories?

Answer:

You can use the find command: find . -type f -size +10M. This command searches the current directory (.) for files (-type f) that are larger than (+) 10 megabytes (10M).


Explain the concept of 'piping' in the shell.

Answer:

Piping (|) is a mechanism to connect the standard output of one command to the standard input of another command. This allows for chaining multiple commands together to perform complex operations, where the output of one command becomes the input for the next.


What is the significance of the ~ (tilde) character in the shell?

Answer:

The ~ (tilde) character is a shorthand notation that expands to the current user's home directory. For example, cd ~/documents will change the directory to the documents folder within the user's home directory.


How do you view the contents of a compressed gzipped file without decompressing it?

Answer:

You can use the zcat command. For example, zcat file.gz will display the uncompressed content of file.gz to standard output without creating a decompressed file on disk.


What is the purpose of the chmod command?

Answer:

chmod (change mode) is used to change file and directory permissions. It controls who can read, write, or execute a file. Permissions can be set using symbolic modes (e.g., u+x) or octal notation (e.g., 755).


Advanced Scripting and Programming

Explain the difference between 'source' and executing a script directly (e.g., './script.sh').

Answer:

Sourcing a script (source script.sh or . script.sh) executes it in the current shell environment, meaning any variables or functions defined become part of the current shell. Executing directly (./script.sh) runs the script in a new subshell, so changes to the environment are not propagated back to the parent shell.


How do you handle errors and exit codes in a shell script?

Answer:

Errors are typically handled by checking the exit status of commands using $?. A non-zero exit status indicates an error. You can use set -e to exit immediately if a command fails, or trap to execute a command upon exit or specific signals.


Describe the purpose of 'set -euxo pipefail' at the beginning of a script.

Answer:

set -e exits immediately if a command exits with a non-zero status. set -u treats unset variables as errors. set -x prints commands and their arguments as they are executed. set -o pipefail causes a pipeline to return the exit status of the last command that returned a non-zero status, rather than just the last command in the pipe.


How can you pass arguments to a shell script and access them?

Answer:

Arguments are passed directly after the script name (e.g., ./script.sh arg1 arg2). Inside the script, they are accessed using positional parameters: $1 for the first argument, $2 for the second, and so on. $# gives the total number of arguments, and $@ expands to all arguments as separate words.


Explain the concept of 'here documents' and provide a simple example.

Answer:

A 'here document' allows you to feed multiple lines of input to a command as if they were typed on the keyboard, without creating a temporary file. It's denoted by << DELIMITER. Example: cat << EOF Hello World EOF.


What is a 'trap' command and when would you use it?

Answer:

The trap command allows you to execute a command when the shell receives a signal (e.g., SIGINT for Ctrl+C, SIGTERM for termination) or when the shell exits. It's commonly used for cleanup operations, like removing temporary files, ensuring resources are released even if the script is interrupted.


How do you perform arithmetic operations in Bash?

Answer:

Arithmetic operations in Bash are typically performed using ((...)) or $[...]. For example, result=$((5 + 3)) or result=$[5 + 3]. The expr command can also be used but is older and less efficient for simple integer arithmetic.


Describe how to debug a shell script.

Answer:

Debugging can be done by adding set -x at the beginning of the script or by running bash -x script.sh. This prints each command before it's executed. You can also insert echo statements to print variable values at different stages of execution.


What is the difference between [[ and [ for conditional expressions?

Answer:

[[ is a Bash keyword that offers more advanced features than the POSIX-compliant [ (which is an external command). [[ supports pattern matching (=~), logical operators (&&, ||), and avoids word splitting and pathname expansion, making it safer and more powerful for string and file tests.


How would you write a function in Bash and call it?

Answer:

Functions are defined using function_name() { commands; } or function function_name { commands; }. They are called by simply typing their name. Arguments are passed to functions just like to scripts, using positional parameters ($1, $2, etc.) within the function's scope. Example: my_func() { echo $1; }; my_func 'hello'.


Scenario-Based Problem Solving

You need to find all files larger than 10MB in the current directory and its subdirectories, then list their paths and sizes in a human-readable format. How would you do this?

Answer:

Use find . -type f -size +10M -exec du -h {} \;. find locates files, -type f specifies files, -size +10M filters by size, and -exec du -h {} \; executes du -h for each found file.


A log file /var/log/app.log is growing rapidly. You need to extract all lines containing the word 'ERROR' from the last 24 hours and save them to a new file errors_today.log. Assume log entries start with a timestamp.

Answer:

First, determine the timestamp for 24 hours ago. Then, use grep with awk or sed to filter. Example: grep 'ERROR' /var/log/app.log | awk '$1 >= "$(date -d '24 hours ago' +'%Y-%m-%d')"' > errors_today.log. A more robust solution might involve logrotate or journalctl if available.


You have a CSV file data.csv with columns Name,Age,City. You need to sort it by Age in descending order and then by Name in ascending order, outputting only Name and City.

Answer:

Use sort with cut and awk. (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1n) to sort. Then cut -d',' -f1,3 or awk -F',' '{print $1 "," $3}' to select columns. Combining: (head -n 1 data.csv; tail -n +2 data.csv | sort -t',' -k2nr -k1) | awk -F',' '{print $1 "," $3}'.


A script myscript.sh is running in the background, but you suspect it's stuck. How would you check its status, and if it's unresponsive, how would you terminate it gracefully, then forcefully if necessary?

Answer:

Check status with ps aux | grep myscript.sh. To gracefully terminate, use kill <PID>. If it doesn't respond, use kill -9 <PID> for a forceful termination. Always try graceful termination first to allow cleanup.


You need to create a backup of the /etc directory, compress it using gzip, and store it in /tmp/etc_backup_YYYYMMDD.tar.gz. How would you automate this?

Answer:

Use tar with gzip. tar -czf /tmp/etc_backup_$(date +%Y%m%d).tar.gz /etc. This command creates a gzipped tar archive (-c create, -z gzip, -f filename) with a date-stamped name.


You're troubleshooting a network issue. How would you check if a specific port (e.g., 8080) is open and listening on your local machine, and what process is using it?

Answer:

Use netstat -tulnp | grep :8080 or lsof -i :8080. netstat shows network connections, -t TCP, -u UDP, -l listening, -n numeric, -p process ID. lsof lists open files, including network sockets.


You need to download a file from a URL (http://example.com/file.zip) and save it as downloaded_file.zip in the current directory. How would you do this using a command-line tool?

Answer:

Use wget or curl. With wget: wget -O downloaded_file.zip http://example.com/file.zip. With curl: curl -o downloaded_file.zip http://example.com/file.zip. Both tools are common for HTTP/HTTPS downloads.


You have a directory with many files, and you need to rename all files ending with .txt to end with .log instead. How would you accomplish this?

Answer:

Use a for loop with mv. for f in *.txt; do mv "$f" "${f%.txt}.log"; done. The "${f%.txt}.log" syntax removes the .txt suffix and appends .log.


You need to find the top 5 largest files in the /var directory, excluding subdirectories like /var/cache and /var/log.

Answer:

Use du and sort. du -ah --exclude=/var/cache --exclude=/var/log /var | sort -rh | head -n 5. du -ah lists sizes in human-readable format, sort -rh sorts numerically in reverse, and head -n 5 gets the top 5.


A script needs to run every day at 3 AM. How would you schedule this task?

Answer:

Use cron. Add an entry to the crontab: 0 3 * * * /path/to/your/script.sh. This means at minute 0, hour 3, every day of the month, every month, and every day of the week, execute the script.


Role-Specific Questions (Developer, Administrator, DevOps)

Developer: How would you debug a shell script that is failing intermittently without clear error messages?

Answer:

I would start by adding set -x at the beginning of the script to enable tracing, which shows commands and their arguments as they are executed. For more targeted debugging, I'd use echo statements to print variable values at critical points. Redirecting stderr to a file (2> error.log) can also help capture elusive errors.


Developer: Explain the difference between $() and `` (backticks) for command substitution.

Answer:

Both $() and ``(backticks) perform command substitution, executing a command and replacing it with its output. However,$() is generally preferred because it allows for nesting without complex escaping and is more readable. Backticks require escaping nested backticks, making them harder to manage.


Developer: Write a shell script to find all files larger than 10MB in a given directory and its subdirectories, then list them by size in descending order.

Answer:

find /path/to/dir -type f -size +10M -print0 | xargs -0 du -h | sort -rh

This command uses find to locate files, xargs to pass them to du for size reporting, and sort -rh to sort by human-readable size in reverse order.


Administrator: How would you monitor disk space usage on a Linux server and set up an alert if it exceeds 90%?

Answer:

I would use df -h to check disk space. To automate alerts, I'd write a script that parses df output, checks the percentage for critical partitions, and then uses mail or a messaging API (like Slack webhook) to send an alert if the threshold is crossed. This script would be scheduled via cron.


Administrator: Describe the steps to automate a daily backup of a specific directory to a remote server using SSH.

Answer:

First, ensure SSH key-based authentication is set up between the source and destination servers to avoid password prompts. Then, use rsync -avz /source/dir/ user@remote:/destination/dir/ within a shell script. Schedule this script to run daily using a cron job, ensuring proper logging and error handling.


Administrator: What is the purpose of the /etc/fstab file, and what are common issues you might encounter with it?

Answer:

/etc/fstab defines static file systems to be mounted at boot time. Common issues include incorrect device paths, wrong file system types, or invalid mount options, which can lead to boot failures or partitions not being mounted. Using nofail can prevent boot issues for non-critical mounts.


DevOps: How do you ensure idempotency in your shell scripts for infrastructure provisioning?

Answer:

Idempotency means running a script multiple times yields the same result as running it once. I achieve this by checking for the existence of resources before creating them (e.g., if [ ! -f /path/to/file ]; then ... fi). For package installations, I use package managers that handle idempotency (e.g., apt install -y package only installs if not present). Configuration management tools like Ansible or Puppet inherently provide idempotency.


DevOps: Explain how you would use a shell script in a CI/CD pipeline to deploy an application.

Answer:

In a CI/CD pipeline, a shell script would typically handle tasks like fetching artifacts, stopping existing services, deploying new code (e.g., copying files, extracting archives), running database migrations, and starting services. It would include error handling and logging, often interacting with systemctl or docker commands. Environment variables would be used for configuration.


DevOps: What are some best practices for writing robust and maintainable shell scripts in a team environment?

Answer:

Best practices include using set -euo pipefail for error handling, adding comments, using functions to modularize code, consistent naming conventions, validating inputs, and providing clear usage instructions. Version control, linting tools (like ShellCheck), and thorough testing are also crucial for team collaboration and maintainability.


DevOps: How would you handle secrets (e.g., API keys, passwords) in shell scripts within a CI/CD context?

Answer:

Secrets should never be hardcoded. In CI/CD, I would use environment variables provided by the CI/CD platform (e.g., Jenkins credentials, GitLab CI/CD variables). For more sensitive or complex scenarios, I'd integrate with a secrets management system like HashiCorp Vault or AWS Secrets Manager, retrieving secrets at runtime rather than storing them in scripts or repositories.


Practical Scripting and Hands-on Tasks

Write a shell script that takes a directory path as an argument and counts the number of regular files and subdirectories within it. Handle cases where the directory doesn't exist.

Answer:

#!/bin/bash
DIR="$1"
if [ ! -d "$DIR" ]; then
  echo "Error: Directory '$DIR' not found."
  exit 1
fi
files=$(find "$DIR" -maxdepth 1 -type f | wc -l)
dirs=$(find "$DIR" -maxdepth 1 -type d | wc -l)
## Subtract 1 from dirs for the directory itself
echo "Files: $files, Directories: $((dirs - 1))"

How would you find all files larger than 10MB in the current directory and its subdirectories, and then list them sorted by size?

Answer:

Use find . -type f -size +10M -print0 | xargs -0 du -h | sort -rh. find locates files, -print0 and xargs -0 handle special characters, du -h gets human-readable sizes, and sort -rh sorts by size in reverse human-readable order.


Write a one-liner to replace all occurrences of 'foo' with 'bar' in all .txt files in the current directory.

Answer:

find . -maxdepth 1 -type f -name "*.txt" -exec sed -i 's/foo/bar/g' {} \;

This uses find to locate .txt files and sed -i for in-place replacement. Alternatively, grep -lR foo *.txt | xargs sed -i 's/foo/bar/g'.


Explain the difference between $$ and $! in shell scripting.

Answer:

$$ expands to the process ID (PID) of the current shell. $! expands to the PID of the most recently executed background (asynchronous) command. They are useful for creating unique temporary files or managing background processes.


How do you parse command-line arguments in a shell script, specifically named arguments like --file <path> or -v?

Answer:

Use getopts for short options (-v) or a while getopts loop. For long options (--file), a while true; do case "$1" in ... esac; shift; done loop with case statements is common, often combined with shift to consume arguments.


Write a script that monitors a log file (/var/log/syslog for example) and prints new lines as they are added, similar to tail -f.

Answer:

#!/bin/bash
tail -f /var/log/syslog

This leverages the tail -f command directly, which is designed for this purpose. For a more manual approach, one could use inotifywait or a loop with wc -l and sed.


How would you ensure a shell script exits immediately if any command fails?

Answer:

Add set -e at the beginning of the script. This option causes the shell to exit immediately if a command exits with a non-zero status. It's crucial for robust script execution.


You have a CSV file data.csv with columns Name,Age,City. How would you extract only the Name and City columns using standard shell tools?

Answer:

cut -d',' -f1,3 data.csv

This uses cut with a comma delimiter (-d',') to select the first and third fields (-f1,3). Alternatively, awk -F',' '{print $1 "," $3}' data.csv can achieve the same.


Write a function in a shell script that takes two numbers as arguments and returns their sum.

Answer:

#!/bin/bash
sum_numbers() {
  echo $(($1 + $2))
}
result=$(sum_numbers 10 5)
echo "Sum: $result"

Functions are defined with function_name() { ... }. Arithmetic expansion $((...)) is used for calculations. The result is typically echoed and captured by command substitution.


How do you schedule a script to run every day at 3 AM?

Answer:

Use cron. Add an entry to the crontab file (crontab -e) like 0 3 * * * /path/to/your_script.sh. The fields represent minute, hour, day of month, month, and day of week, respectively.


Troubleshooting and Debugging Shell Scripts

Shell Best Practices and Performance Optimization

How can you optimize a shell script for performance when dealing with large files or many iterations?

Answer:

Avoid unnecessary forks (e.g., using grep inside a loop). Use built-in shell features where possible (e.g., parameter expansion instead of sed). Process data in chunks or use awk for efficient line-by-line processing.


Explain the difference between $(command) and `command` for command substitution and which is preferred for best practice.

Answer:

$(command) is the modern and preferred syntax. It handles nesting more easily and avoids issues with backslashes and quoting that can occur with backticks (`command`). $(command) is generally more readable and robust.


What is the purpose of set -e and set -u in a shell script, and why are they considered good practice?

Answer:

set -e (errexit) causes the script to exit immediately if a command exits with a non-zero status. set -u (nounset) treats unset variables as an error and exits. Both improve script robustness by catching errors early and preventing unexpected behavior.


How do you prevent 'globbing' or pathname expansion in a shell script?

Answer:

To prevent globbing, enclose the string in double quotes. For example, ls "*.txt" will treat *.txt as a literal string, whereas ls *.txt will expand to all .txt files in the current directory.


When should you use [[ ... ]] instead of [ ... ] for conditional expressions in Bash?

Answer:

[[ ... ]] is a Bash-specific keyword that offers more features than the POSIX-compliant [ ... ] command. It supports pattern matching (=~), logical operators (&&, ||), and avoids word splitting and pathname expansion, making it safer and more powerful.


Describe a scenario where using xargs would be more efficient than a for loop.

Answer:

xargs is more efficient when processing a large list of items as arguments to a command. It builds command lines with multiple arguments, reducing the number of times the target command is invoked, unlike a for loop which typically calls the command once per item.


What is the significance of redirecting stderr to /dev/null (e.g., 2>/dev/null)?

Answer:

Redirecting stderr to /dev/null discards error messages, preventing them from being displayed on the console or polluting output. This is useful for suppressing expected errors or when you only care about stdout.


How can you make a shell script more portable across different Unix-like systems?

Answer:

Use POSIX-compliant commands and features where possible. Avoid Bash-specific extensions like [[ ... ]] or process substitution if strict portability is required. Specify the interpreter explicitly using a shebang like #!/bin/sh.


Why is it generally bad practice to parse ls output in shell scripts?

Answer:

Parsing ls output is problematic because filenames can contain spaces, newlines, or special characters, which can break script logic when processed by tools like awk or for loops. Use find -print0 | xargs -0 for safe filename handling.


What is the purpose of trap in shell scripting, and provide a simple example.

Answer:

trap allows you to execute commands when the shell receives a signal (e.g., EXIT, INT, TERM). It's crucial for cleanup operations. Example: trap 'rm -f /tmp/mytempfile' EXIT ensures a temporary file is removed when the script exits.


Version Control and Collaboration with Shell

How do you typically use Git from the command line for daily development tasks?

Answer:

I primarily use git status, git add, git commit -m "message", git pull, and git push. For branching, I use git checkout -b branch_name and git merge or git rebase.


Explain the difference between git pull and git fetch.

Answer:

git fetch downloads new data from a remote repository but doesn't integrate it into your working files. git pull is essentially git fetch followed by git merge (or git rebase, depending on configuration), integrating the changes into your current branch.


How would you revert a specific commit that has already been pushed to a remote repository?

Answer:

I would use git revert <commit_hash>. This creates a new commit that undoes the changes of the specified commit, preserving the project history. It's safer than git reset --hard for shared branches.


Describe a scenario where you would use git rebase instead of git merge.

Answer:

I'd use git rebase to maintain a clean, linear project history, especially on feature branches before merging into main. It reapplies commits from one branch onto another, avoiding merge commits and making the history easier to read.


How do you resolve merge conflicts using the command line?

Answer:

After a merge conflict, git status shows conflicted files. I manually edit these files to resolve conflicts, then use git add <conflicted_file> to mark them as resolved. Finally, I complete the merge with git commit.


What is git stash and when would you use it?

Answer:

git stash temporarily saves changes that are not ready to be committed, allowing you to switch branches or perform other tasks. It's useful when you need to quickly switch context without committing incomplete work.


How can you view the commit history of a specific file?

Answer:

I use git log -- <file_path>. This command shows all commits that have affected the specified file, including the commit hash, author, date, and commit message.


You accidentally committed sensitive information. How do you remove it from your Git history?

Answer:

For recent, unpushed commits, git reset HEAD~1 followed by amending the commit is an option. For pushed commits or deeper history, git filter-branch or BFG Repo-Cleaner are used to rewrite history, but this is disruptive and requires force-pushing.


Explain the purpose of a .gitignore file.

Answer:

A .gitignore file specifies intentionally untracked files that Git should ignore. This prevents temporary files, build artifacts, or sensitive configuration files from being accidentally committed to the repository.


How do you create and switch to a new branch in Git?

Answer:

To create and switch to a new branch, I use git checkout -b new-branch-name. This command is a shortcut for git branch new-branch-name followed by git checkout new-branch-name.


Security Considerations in Shell Scripting

Why is it dangerous to run shell scripts downloaded from untrusted sources?

Answer:

Untrusted scripts can contain malicious code that could delete files, install malware, steal sensitive data, or create backdoors. They run with the permissions of the user executing them, making them a significant security risk.


How can you prevent command injection vulnerabilities in shell scripts?

Answer:

Always quote variables that contain user input, especially when used in commands. Use set -e and set -u to catch errors and unset variables. Avoid eval with untrusted input. Prefer specific commands over general ones, and validate input rigorously.


Explain the importance of input validation in shell scripting for security.

Answer:

Input validation ensures that data provided to a script conforms to expected formats and values, preventing malicious input from being processed. This mitigates risks like command injection, path traversal, and buffer overflows by rejecting invalid or dangerous characters.


What are the risks of using eval in shell scripts, and when might it be acceptable?

Answer:

eval executes its arguments as shell commands, making it highly susceptible to command injection if used with untrusted input. It's generally acceptable only when the input is entirely controlled and trusted by the script itself, or when dynamically constructing simple, safe commands.


How can you securely handle sensitive information like passwords or API keys in shell scripts?

Answer:

Avoid hardcoding sensitive data directly in scripts. Instead, use environment variables (with caution), secure configuration files with restricted permissions, or dedicated secrets management tools like HashiCorp Vault or AWS Secrets Manager. Never store them in version control.


Why is it important to set appropriate file permissions for shell scripts and their output files?

Answer:

Incorrect file permissions can allow unauthorized users to read, modify, or execute scripts or their output. Scripts should typically be executable only by their owner, and sensitive output files should have restrictive read/write permissions to prevent data leakage or tampering.


What is the purpose of set -u (or set -o nounset) in a shell script for security?

Answer:

set -u causes the script to exit immediately if it tries to use an unset variable. This prevents unexpected behavior or security vulnerabilities that could arise from an uninitialized variable being interpreted as an empty string or a default value, potentially leading to unintended command execution or file operations.


Describe the concept of 'least privilege' in the context of shell script execution.

Answer:

The principle of least privilege dictates that a script should run with the minimum necessary permissions to perform its intended function. This limits the potential damage if the script is compromised, as it won't have elevated access to systems or data it doesn't need.


How can path manipulation lead to security vulnerabilities in shell scripts?

Answer:

If the PATH environment variable is not carefully controlled, a malicious user could inject their own directory containing a similarly named executable (e.g., ls or rm). When the script calls that command, it might execute the malicious version instead of the legitimate one, leading to unintended actions.


What are some best practices for writing secure shell scripts?

Answer:

Validate all user input, quote variables, use set -euo pipefail, avoid eval with untrusted data, set restrictive file permissions, use absolute paths for commands, and follow the principle of least privilege. Regularly audit scripts for vulnerabilities and keep them updated.


Summary

Thorough preparation is paramount for success in Shell's rigorous interview process. By diligently reviewing common questions, understanding Shell's values, and practicing your responses, you significantly enhance your chances of showcasing your capabilities and suitability for the role. This document serves as a valuable resource to guide your preparation, helping you anticipate potential inquiries and formulate compelling answers.

Remember, the journey doesn't end with the interview. The energy industry is dynamic, and continuous learning is key to professional growth. Embrace every opportunity to expand your knowledge and skills, ensuring you remain a valuable asset in a constantly evolving landscape. Your dedication to preparation and lifelong learning will undoubtedly pave the way for a fulfilling career.