89 Bash Interview Questions and Answers (2026)

Bash isn't a legacy skill anymore, it's the glue shipping Python APIs and AI/ML backends to production. More teams lean on it, and interviewers now expect real fluency, not memorized one-liners. Walk in shaky on quoting, redirection, or signals and you'll get exposed fast.
This guide gives you 89 questions with concise, interview-ready answers and code where it counts. It's structured Junior → Mid → Senior, so you build from shell fundamentals up to processes, debugging, and security. Work through it and you'll have answers ready before they finish asking.
Q1.Explain the purpose of the shebang (#!) at the top of a script. What happens if it's missing?
#!) at the top of a script. What happens if it's missing?The shebang is the first line of a script (#!/path/to/interpreter) that tells the kernel which interpreter to use to run the file. Without it, behavior depends on how the file is invoked.
What it does:
When you execute the file directly, the kernel reads the first two bytes #! and runs the named interpreter with the script as an argument.
Common forms: #!/bin/bash or the portable #!/usr/bin/env bash (finds bash via PATH).
If it's missing:
Running it directly (./script) makes the parent shell try to interpret it: often it falls back to /bin/sh, which may lack bash features.
Explicitly invoking bash script ignores the shebang entirely and works fine.
Why it matters: it guarantees the script runs under the intended interpreter regardless of the caller's shell, avoiding subtle syntax errors.
Q2.What is the difference between Bash and other shells like sh or zsh?
sh or zsh?They are all command-line shells, but they differ in feature set and POSIX scope: sh is the minimal standard, bash extends it for scripting, and zsh extends it further for interactive use.
sh (POSIX shell): The baseline specification; on many systems it's a symlink to a small shell (dash). Maximally portable, minimal features.
bash (Bourne Again Shell): Superset of sh with arrays, [[ ]], $(()) arithmetic, brace expansion, and process substitution. The de facto Linux default.
zsh (Z shell): Largely bash-compatible but adds powerful interactive features: better globbing, spelling correction, themeable prompts, plugin ecosystems. Default on modern macOS.
Practical rule: write scripts for sh or bash for portability; use zsh mainly for an enhanced interactive shell.
Q3.Explain the role of the Kernel vs. the Shell in a Linux system.
The kernel is the core of the OS that directly manages hardware and resources; the shell is a user-space program that translates your typed commands into requests the kernel can carry out. The shell is an interface, the kernel is the engine.
Kernel:
Manages CPU scheduling, memory, file systems, devices, and processes.
Exposes services only through system calls (read, write, fork, exec); runs in privileged mode.
Shell:
A command interpreter (bash, zsh) that parses input, expands variables/globs, and launches programs.
Runs in user mode and reaches the kernel indirectly via system calls.
The relationship: you type into the shell, the shell asks the kernel, the kernel touches hardware and returns results. Many shells can run on one kernel.
Q4.Explain the difference between a 'shell' and a 'terminal'.
A terminal is the program (or device) that provides the text input/output window; the shell is the command interpreter that runs inside it. The terminal handles display and keystrokes, the shell decides what your commands mean.
Terminal (emulator):
Examples: GNOME Terminal, iTerm2, xterm. Originally physical teletype devices.
Manages the screen, fonts, keyboard input, and a pseudo-terminal device (pty) connecting it to a program.
Shell: The program running inside the terminal (bash) that reads the typed line, interprets it, and runs commands.
Analogy: the terminal is the phone handset; the shell is the person you're talking to. You can run a shell without a terminal (in a script) and a terminal can run things other than a shell.
Q5.What is the difference between a local variable and an environment variable in Bash?
A local (shell) variable lives only in the current shell process; an environment variable is marked for export so it's copied into the environment of any child process the shell spawns.
Local (shell) variable:
Created by plain assignment like name=value; visible only to the current shell and not to children.
Used for temporary state, loop counters, and script-internal values.
Environment variable:
A variable flagged with export so it's inherited by child processes (its value is copied, not shared).
Used to configure programs you launch (e.g. PATH, HOME).
Inspecting them: set shows all shell variables; env or printenv shows only exported environment variables.
Key point: a child changing an inherited variable does not affect the parent (no propagation back up).
Q6.What is the purpose of the export command? Why can't a child process access a variable without it?
export command? Why can't a child process access a variable without it?export marks a variable so the shell includes it in the environment block it hands to child processes. Without it, the variable stays private to the current shell, so a child never sees it.
How inheritance works:
When a process is created (via fork/exec), only the environment is copied to the child, not the parent's full set of shell variables.
export is what places a variable into that environment.
Why an unexported variable is invisible: A plain assignment lives only in the shell's internal variable table, which children have no access to.
Usage notes:
export VAR exports an existing variable; export VAR=value sets and exports in one step.
VAR=value command exports VAR for just that one command's run.
Q7.Explain how the PATH environment variable works and how Bash uses it to locate executables.
PATH environment variable works and how Bash uses it to locate executables.PATH is a colon-separated list of directories Bash searches, left to right, to find the executable for a command typed without a slash. The first match wins.
Lookup order:
For a bare command name, Bash checks functions and builtins first, then searches each PATH directory in order.
A name containing a / (e.g. ./script.sh) skips PATH entirely.
First match wins: Order matters: earlier directories shadow later ones, so prepending a directory overrides system commands.
Performance: hashing: Bash caches resolved paths in a hash table; hash -r clears it after you move or add executables.
Inspecting and extending:
type cmd or which cmd shows which file would run; export PATH="$HOME/bin:$PATH" to add a directory.
Empty entries or . in PATH mean the current directory, which is a security risk.
Q8.Explain the difference between 'system-defined' and 'user-defined' variables.
System-defined (built-in) variables are set by the shell or environment to configure behavior and carry standard conventions; user-defined variables are ones you create yourself in a session or script.
System-defined variables:
Provided by the shell/OS, conventionally UPPERCASE: HOME, PATH, PWD, USER, SHELL.
Some are special shell variables: $? (last exit code), $$ (PID), $#, $@.
User-defined variables: Created with name=value for your own logic; by convention use lowercase to avoid clashing with system names.
Practical note:
Both kinds behave the same mechanically; the distinction is who owns the convention and what reads them.
Avoid overwriting system variables like PATH carelessly, as it changes shell behavior.
Q9.Explain the difference between && and ; when joining commands.
&& and ; when joining commands.; runs commands sequentially regardless of outcome, while && runs the next command only if the previous one succeeded (exit status 0).
; (sequence):
Always executes each command in turn; the success or failure of one doesn't affect the next.
Use when steps are independent.
&& (conditional AND):
Runs the next command only if the previous exit code is 0; short-circuits (stops) on failure.
Use when a step depends on the previous one succeeding.
Related operator: || is the opposite: it runs the next command only if the previous one failed.
Q10.What are the different types of loops available in Bash, and when would you use a 'for' loop versus a 'while' loop versus an 'until' loop?
for' loop versus a 'while' loop versus an 'until' loop?Bash has for, while, and until loops: use for to iterate a known list, while to loop as long as a condition stays true, and until to loop until a condition becomes true.
for: iterate over a known set:
Best when the items are knowable up front: a list of words, files from a glob, or a numeric range.
Two forms: list-based (for x in a b c) and C-style (for ((i=0;i<n;i++))).
while: loop while condition is true:
Best when the iteration count is unknown: reading lines until EOF, polling until something succeeds.
Common idiom: while read -r line; do ...; done < file.
until: loop until condition becomes true:
Logical inverse of while: runs while the test is false, stops once it is true.
Reads naturally for waiting: until ping -c1 host; do sleep 1; done.
Q11.What is the 'case' statement, and when is it preferable to a chain of if-elif statements?
case' statement, and when is it preferable to a chain of if-elif statements?The case statement matches a single value against multiple patterns and runs the first matching branch. It is preferable when you are testing one variable against many possible values or glob patterns, where it is cleaner and faster to read than a long if-elif chain.
Pattern matching, not just equality: Patterns use shell globbing: *, ?, [...], and alternation with |.
Each branch ends with ;;: Only the first matching pattern runs; *) acts as the default catch-all.
Prefer case over if-elif when: You branch on one value against many literals or patterns (menu choices, argument parsing, file extensions).
Prefer if-elif when: Conditions are heterogeneous (numeric comparisons, different variables, command exit codes).
Q12.How does short-circuit evaluation work with && and ||, and how can you use it for conditional execution?
&& and ||, and how can you use it for conditional execution?Short-circuit evaluation means Bash stops evaluating a logical chain as soon as the outcome is decided: && runs the next command only if the previous one succeeded (exit 0), and || runs it only if the previous one failed (non-zero). This lets you express conditional execution without an explicit if.
&& = run on success: cmd1 && cmd2: cmd2 runs only if cmd1 exits 0; otherwise it is skipped.
|| = run on failure: cmd1 || cmd2: cmd2 runs only if cmd1 exits non-zero.
Based on exit status: Everything keys off $?: 0 is true/success, non-zero is false/failure.
Common idioms:
Guard then act: mkdir /tmp/x && cd /tmp/x.
Fallback or fail: command -v jq || { echo 'need jq'; exit 1; }.
Caveat with chaining: a && b || c is not a clean if/else: c also runs if b fails. Use a real if when that matters.
Q13.What is the difference between 'Single Quotes' and 'Double Quotes' regarding variable expansion and command substitution?
Single quotes are literal: nothing inside them is interpreted. Double quotes are 'soft': they suppress word splitting and globbing but still allow variable expansion, command substitution, and arithmetic expansion.
Single quotes ('...'):
Every character is literal: $var, $(cmd), and backticks are NOT expanded.
You cannot put a single quote inside single quotes (no escaping).
Double quotes ("..."):
Expands $var, ${var}, $(cmd), and $((...)).
Prevents word splitting and globbing, so spaces and * inside the value stay intact.
Practical guidance: Default to double-quoting expansions ("$var") to avoid splitting bugs; use single quotes for fixed literal text.
Q14.What is command substitution, and what is the difference between using backticks and the $( ) syntax?
$( ) syntax?Command substitution runs a command and replaces the expression with that command's standard output (trailing newlines trimmed). The two syntaxes, backticks `...` and $(...), do the same job, but $(...) is the modern, preferred form because it nests cleanly and is easier to read.
What it does: Captures stdout into a value: now=$(date).
$(...) advantages:
Nests without escaping: $(echo $(date)).
No confusing backslash rules; clearer with surrounding quotes and parentheses.
Backtick drawbacks:
Nesting requires escaping inner backticks (\`), which gets ugly fast.
Backslashes are handled differently inside backticks, causing surprises.
Common gotcha: Always quote the result ("$(cmd)") to prevent word splitting and globbing of the output.
Q15.Explain the difference between > and >>.
> and >>.Both redirect stdout to a file, but > truncates (overwrites) the file, while >> appends to the end, preserving existing content.
> overwrites:
Creates the file if absent, or truncates it to zero length first, then writes.
echo hi > log replaces all prior contents.
>> appends:
Creates the file if absent, otherwise writes at the end.
echo hi >> log keeps history (good for logs).
Safety note: set -o noclobber makes > refuse to overwrite an existing file; use >| to force it.
Q16.Explain the concept of 'pipes' in Unix. How does data flow between processes?
A pipe (|) connects the stdout of one process to the stdin of the next, letting small programs be composed into a data-processing chain.
How it works:
The kernel creates an in-memory buffer; the left process writes to its write-end, the right reads from its read-end.
Processes run concurrently, not sequentially: data flows as it is produced.
Flow control: if the buffer fills, the writer blocks until the reader consumes; the reader blocks waiting for data.
Only stdout flows by default: stderr is not piped unless redirected (2>&1 | or |&).
Subshell caveat: Each segment runs in its own subshell, so variable changes in the last stage don't persist in the parent shell.
Exit status is that of the last command unless pipefail is set.
Q17.How do you access the exit status of the most recently executed command, and what does a non-zero value typically indicate?
The special variable $? holds the exit status of the most recently completed command; 0 means success and any non-zero value indicates failure.
Reading it: Capture immediately, since the next command overwrites it: status=$?.
What non-zero means:
A general error is often 1; misuse of a builtin is 2.
126 = command found but not executable; 127 = command not found.
128+N = terminated by signal N (e.g. 130 = Ctrl-C / SIGINT).
Practical use:
Branch on success: if cmd; then ... tests the status implicitly.
In a pipeline, $? is the last command's status unless pipefail is set.
Q18.What is the difference between chmod, chown, and chgrp?
chmod, chown, and chgrp?They change different attributes: chmod changes permission bits, chown changes the owning user (and optionally group), and chgrp changes only the group.
chmod:
Sets read/write/execute for user, group, other.
Symbolic (chmod u+x file) or octal (chmod 755 file).
chown:
Changes the owner: chown alice file; can set both with chown alice:devs file.
Usually requires root.
chgrp: Changes only the group: chgrp devs file (equivalent to chown :devs file).
Ownership (chown/chgrp) decides which permission class applies; chmod decides what that class can do.
Q19.What is the difference between the break and continue commands inside a loop?
break and continue commands inside a loop?Both alter loop flow: break exits the loop entirely, while continue skips the rest of the current iteration and moves to the next one.
break:
Terminates the loop immediately; execution resumes after the loop.
Use it once a search succeeds or a stop condition is met.
continue:
Jumps to the next iteration, skipping remaining statements in the body.
Use it to skip items that fail a filter.
Numeric levels: Bash accepts break 2 or continue 2 to act on an enclosing outer loop.
Q20.What is the difference between absolute and relative paths, and how does the shell resolve them?
An absolute path starts from the filesystem root and is unambiguous everywhere, while a relative path is interpreted from the current working directory. The shell resolves a relative path by joining it to $PWD.
Absolute paths: Begin with / (e.g. /etc/hosts); meaning never depends on where you are.
Relative paths:
Do not start with /; resolved against the current directory.
`.` is the current dir, `..` is the parent, so ../logs/app.log walks up then down.
How the shell resolves them:
Leading / means start at root; otherwise prepend $PWD then collapse . and ...
Bare command names are different: those are searched in $PATH, which is why you run a local script as ./script.sh.
Q21.What is the difference between a function and an alias in Bash? When would you use one over the other?
An alias is a simple text substitution for a command name, while a function is a named block of shell code that can take arguments and run logic. Use an alias for a short fixed shortcut, a function when you need parameters or multiple statements.
Alias:
Defined with alias ll='ls -la'; just expands at the start of a command.
Cannot truly handle positional arguments and is off by default in non-interactive scripts.
Function:
Accepts arguments via $1, $@; can hold loops, conditionals, locals, and a return code.
Works in scripts and is the right tool for real logic.
Rule of thumb: trivial rename of a command, use an alias; anything needing arguments or logic, use a function.
Q22.What is the difference between 'exit' and 'return' in a Bash script?
exit' and 'return' in a Bash script?exit terminates the entire script (or shell) with a given status, while return only exits the current function (or sourced script) and hands control back to the caller.
exit ends the process:
Stops the whole script immediately with status exit N (defaults to status of last command).
If you source a script that calls exit, it kills your interactive shell too: a common gotcha.
return ends a function:
Returns control and an exit status to the caller; the script keeps running.
Only valid inside a function or a sourced script: using it elsewhere is an error.
Both default to the exit status of the last executed command if no number is given.
Q23.What is the purpose of the 'read' command, and how can you use it to capture user input?
read' command, and how can you use it to capture user input?read reads a line from standard input (keyboard, file, or pipe) and assigns it to one or more variables. It's the standard way to capture interactive user input or process input line by line.
Basic usage:
read name waits for input and stores it in $name.
Multiple variables split the line on $IFS: read first last.
Useful options:
-p: display a prompt (read -p "Name: " name).
-s: silent input, ideal for passwords.
-r: raw mode, don't treat backslash as escape (almost always use this).
-t: timeout; -n: stop after N characters.
Reading a file line by line: Combine with a while loop and input redirection.
Q24.What is a subshell, and how is it created?
A subshell is a child process forked from the current shell that inherits a copy of its environment, then runs commands independently: changes made inside it do not affect the parent.
What it is: A separate process (via fork()) with its own copy of variables, working directory, and shell state.
How it is created:
Explicit grouping with parentheses: ( cd /tmp; ls ).
Command substitution: $(...) or backticks.
Each side of a pipeline: cmd1 | cmd2 (each runs in its own subshell, unless lastpipe applies).
Backgrounding with & and process substitution <(...).
Contrast with { ...; } which groups commands in the current shell (no subshell).
Q25.What is the purpose of the nohup command?
nohup command?nohup runs a command immune to the hangup signal (SIGHUP), so it keeps running after you log out or your terminal closes. It detaches the command's life from the controlling terminal.
The problem it solves:
When a shell session ends, the kernel sends SIGHUP to its processes, killing them by default.
nohup makes the process ignore SIGHUP.
Behavior details:
It redirects stdout/stderr to nohup.out if output is going to a terminal.
Usually combined with & to also background the job: nohup ./long.sh &.
Alternatives: disown (remove an already-running job from the shell), or tmux/screen / systemd-run for fuller session management.
Q26.What is the difference between an 'interactive' shell and a 'non-interactive' shell?
An interactive shell reads commands typed by a user at a prompt; a non-interactive shell runs commands from a script or pipe with no prompt and no human in the loop.
Interactive:
Has a prompt (PS1), command history, job control, and line editing.
Detect it: $- contains i, or test [[ $- == *i* ]].
Non-interactive: Created when running a script, a command | bash pipe, or a cron job. No prompt, no history.
Why it matters:
Startup files differ: interactive non-login shells read .bashrc; non-interactive shells generally read none unless BASH_ENV is set.
This is why aliases defined in .bashrc don't apply inside scripts.
Q27.Explain the difference between a 'login' shell and a 'non-login' shell. Why does it matter for .bashrc vs .bash_profile?
.bashrc vs .bash_profile?A login shell is the first shell started when you authenticate (console login, SSH); a non-login shell is any shell started afterward without logging in (opening a new terminal tab). They read different startup files, which is why your config is split.
Login shell:
Started at authentication; reads /etc/profile then the first found of ~/.bash_profile, ~/.bash_login, ~/.profile.
Best place for environment variables and PATH exports that should be inherited by all child processes.
Non-login (interactive) shell: Reads ~/.bashrc. Best place for aliases, functions, and prompt settings you want in every new terminal.
The common convention: Since login shells skip .bashrc, people source it from .bash_profile so aliases load everywhere.
Q28.What is the difference between sourcing a script and executing it normally?
Sourcing (source script or . script) runs the script's commands in the current shell, so its variables and functions persist; executing it (./script) spawns a child subshell whose changes vanish when it exits.
Sourcing:
No new process; the current shell reads and runs each line.
Variable assignments, cd, aliases, and functions affect your session. This is why you source ~/.bashrc to reload config.
Executing:
Forks a child shell (needs execute permission and usually a shebang).
The child inherits exported variables but cannot mutate the parent: its cd or variable changes are discarded on exit.
Rule of thumb: source when the script must modify your environment; execute when it's a standalone tool.
Q29.What is the Internal Field Separator (IFS), and how does it affect word splitting?
IFS), and how does it affect word splitting?IFS is a special shell variable holding the characters Bash uses to split unquoted expansions into separate words. By default it's space, tab, and newline, and changing it changes how text gets tokenized.
Default behavior:
Default IFS=$' \t\n': runs of these split words and leading/trailing ones are trimmed.
Word splitting applies to unquoted $var and $(...), which is why quoting ("$var") prevents it.
Custom IFS:
Set it to parse delimited data, e.g. IFS=, to split CSV fields or loop over PATH with IFS=:.
With a non-whitespace IFS, empty fields are preserved (consecutive delimiters create blanks).
Good practice:
Scope the change: IFS=, read -ra parts <<< "$line" only affects that command.
Use IFS= (empty) with read -r to read a whole line without trimming whitespace.
Q30.Why is Bash considered a 'weakly typed' language, and what are the implications for variable manipulation?
Bash is weakly typed because variables have no declared type by default: every value is essentially a string, and Bash decides how to interpret it (number, path, text) based on the operator and context you use.
Everything is a string by default: x=5 and x="5" are identical; numeric meaning comes from the context, not the variable.
Context decides interpretation:
Arithmetic contexts $(( )) or -eq treat values as integers; = / == in tests treat them as strings.
5 -eq 05 is true (numeric), but "5" = "05" is false (string).
Implications:
Easy mixing of text and numbers, but silent surprises: choosing the wrong operator gives wrong comparisons rather than an error.
Bash has no floats; arithmetic is integer-only (use bc or awk for decimals).
Optional typing with declare: declare -i forces integer arithmetic on assignment; declare -a/declare -A make arrays; declare -r makes read-only.
Q31.What is the difference between an array and an associative array in Bash, and how do you declare each?
An indexed array maps integer indices to values; an associative array maps arbitrary string keys to values. Indexed arrays work in any modern Bash; associative arrays require Bash 4+ and must be declared explicitly with declare -A.
Indexed array:
Zero-based integer keys; declare with declare -a arr or just arr=(a b c).
Access ${arr[0]}, all elements ${arr[@]}, indices ${!arr[@]}.
Associative array:
String keys; declare -A is mandatory before use (otherwise keys collapse to integer 0).
Assign map[name]=value; access ${map[name]}; list keys with ${!map[@]}.
Common to both: Length is ${#arr[@]}; always quote "${arr[@]}" to preserve elements with spaces.
Q32.Explain the difference between the [[ ]] and [ ] test constructs. Why is the double-bracket version generally preferred in Bash?
[[ ]] and [ ] test constructs. Why is the double-bracket version generally preferred in Bash?[ ] is the POSIX test command, while [[ ]] is a Bash keyword with richer, safer syntax. [[ ]] is preferred in Bash because it avoids word-splitting and globbing pitfalls and adds pattern and regex matching.
[ ] is a command:
It's actually a program/builtin, so its arguments undergo word-splitting and globbing; unquoted empty variables break it.
Portable to POSIX sh; required when writing for non-Bash shells.
[[ ]] is a keyword:
Bash parses it specially, so variables aren't word-split or glob-expanded: [[ $x == foo ]] is safe even if $x is empty.
Supports &&, ||, pattern matching with ==, and regex with =~.
Practical takeaway:
Use [[ ]] in Bash scripts; reserve [ ] for strict POSIX portability.
For arithmetic, prefer (( )).
Q33.Why does an if statement often fail with a 'command not found' error if there are no spaces inside the brackets?
if statement often fail with a 'command not found' error if there are no spaces inside the brackets?Because [ is not punctuation in Bash: it is actually a command (a builtin, and also /usr/bin/[). Like any command, it must be separated from its arguments by spaces, or the shell reads everything as one token it cannot find.
[ is a command, not syntax: if [ ... ] really means: run the command [ with arguments, and ] is its required final argument.
No spaces fuses tokens: [$x becomes one word like [5, and there is no command named [5, hence 'command not found'.
The closing bracket needs space too: 5] jams the value into ], so [ never sees its expected terminator.
[[ ]] is the same rule: It is a keyword rather than a command, but still requires surrounding spaces as word boundaries.
Q34.Explain the difference between $* and $@ when handling positional parameters. When does quoting them change the behavior?
$* and $@ when handling positional parameters. When does quoting them change the behavior?Both $* and $@ expand to all positional parameters, and unquoted they behave identically. The difference appears only when quoted: "$@" preserves each argument as a separate word, while "$*" joins them into a single string.
Unquoted: identical (and risky): $* and $@ both word-split and glob each argument, breaking ones with spaces.
"$@": preserves arguments: Expands to "$1" "$2" ...: each parameter stays one distinct word, even with embedded spaces. This is almost always what you want.
"$*": joins into one word: Expands to a single string with arguments separated by the first character of IFS (a space by default): "$1 $2 $3".
Rule of thumb: Use "$@" to forward arguments to another command; use "$*" only when you deliberately want one joined string.
Q35.Why is it considered a best practice to quote variables (e.g., "$VAR")? What is 'word splitting'?
"$VAR")? What is 'word splitting'?Quoting a variable like "$VAR" preserves its value as a single intact word; unquoted, the shell splits it on whitespace and expands globs, which corrupts arguments containing spaces, tabs, or wildcard characters.
What word splitting is:
After expansion, the shell breaks unquoted results into separate words at characters in IFS (space, tab, newline by default).
It also performs filename/glob expansion on the result.
Why it bites you:
file="my file.txt"; rm $file tries to delete two files (my and file.txt); rm "$file" is correct.
Empty/unset variables vanish entirely unquoted, dropping an argument.
Rule of thumb: Always quote expansions unless you specifically want splitting or globbing. For arrays, use "${arr[@]}".
Q36.What are 'metacharacters' (or wildcards) in Bash, and how does the shell expand them before executing a command?
Metacharacters (globbing wildcards) are special characters the shell expands into matching filenames before the command runs; the command itself never sees the pattern, only the resulting list of names.
The main glob wildcards:
*: matches any string (including empty).
?: matches exactly one character.
[abc] / [a-z]: matches one character from a set/range.
How expansion works:
The shell (not the program) replaces the pattern with all matching filenames in the current directory.
ls *.txt becomes ls a.txt b.txt before ls is executed.
Key behaviors:
If nothing matches, Bash by default leaves the pattern literal (unless nullglob or failglob is set).
Quoting disables expansion: "*.txt" stays literal.
Q37.When would you use 2>&1 in a command, and what does it actually do?
2>&1 in a command, and what does it actually do?2>&1 redirects stderr (fd 2) to wherever stdout (fd 1) currently points, so both streams go to the same destination: you use it to capture or log error output together with normal output.
What it means literally: 2 is stderr, 1 is stdout; &1 means "the current target of fd 1," not a file named 1.
Order matters:
cmd > file 2>&1 sends both to file: fd 1 is pointed at the file first, then fd 2 copies that target.
cmd 2>&1 > file is different: stderr goes to the terminal (old stdout), and only stdout goes to the file.
Common uses:
Logging everything: ./job.sh > out.log 2>&1.
Piping errors too: cmd 2>&1 | grep error.
Bash shorthand: &> file redirects both at once.
Q38.What are heredocs and herestrings, and when would you use them over standard redirection?
Heredocs and herestrings feed inline text to a command's standard input without needing a separate file, replacing the need to echo piped into the command.
Heredoc (<<):
Streams a multi-line block of text until a delimiter word is seen on its own line.
Variables and command substitution expand inside it; quote the delimiter (<<'EOF') to disable expansion.
Use <<- to strip leading tabs for indentation.
Herestring (<<<):
Feeds a single short string (one expression) to stdin.
Great for passing one variable to a command without echo |.
When to prefer over standard redirection:
You want literal inline content (a config, SQL, a script) without creating a temp file.
Herestrings avoid a subshell and the trailing-newline quirks of pipes.
Q39.Explain what 'xargs' does and a scenario where it is more useful than piping directly to a command.
xargs' does and a scenario where it is more useful than piping directly to a command.xargs reads items from stdin and builds them into arguments for another command, which is essential when a program expects arguments rather than piped stdin.
The core problem it solves:
Many commands (rm, cp, mkdir) take filenames as arguments, not on stdin, so a plain pipe wouldn't work.
echo "$files" | rm fails; ... | xargs rm works.
Useful features:
Batches arguments to avoid "argument list too long" errors.
-P runs jobs in parallel; -n limits args per invocation; -I {} places the item at a chosen position.
Safety: use find ... -print0 | xargs -0 to handle filenames with spaces/newlines.
Scenario where it beats a direct pipe: Deleting thousands of files from a find result: find . -name '*.tmp' -print0 | xargs -0 rm.
Q40.What is the difference between set -e, set -u, and set -o pipefail? Why are they often referred to as Bash Strict Mode?
set -e, set -u, and set -o pipefail? Why are they often referred to as Bash Strict Mode?These three options make Bash fail fast and loudly on errors, undefined variables, and broken pipelines; combined they form the unofficial "strict mode" that catches silent bugs.
set -e (errexit):
Exits the script immediately if any command returns non-zero (with some exceptions in conditionals).
Prevents a script from blindly continuing after a failed step.
set -u (nounset):
Treats references to unset variables as an error instead of expanding to empty.
Catches typos like rm -rf "$dir/" where $dir is undefined.
set -o pipefail:
Makes a pipeline fail if any stage fails, not just the last.
Without it, failing_cmd | tee log reports success because tee succeeded.
Common combined form:
set -euo pipefail (often with IFS=$'\n\t') at the top of robust scripts.
Caveat: -e has surprising edge cases, so test carefully and handle expected failures explicitly.
Q41.How do you implement error handling in a Bash script?
Bash has no exceptions, so error handling means checking exit codes and reacting deliberately: combine set -euo pipefail, explicit $? checks, and trap for cleanup.
Use exit codes: Every command returns 0 for success, non-zero for failure, readable via $?.
Enable safety flags: set -e exits on any unchecked failure, set -u errors on unset variables, set -o pipefail makes a pipeline fail if any stage fails.
Check explicitly when you need to recover: Use if cmd; then ... or cmd || handle_error rather than letting the script die.
Clean up with trap: trap 'cleanup' EXIT ERR runs on exit or error to remove temp files, release locks, etc.
Report to stderr and exit non-zero: Send messages to >&2 and exit with a meaningful code so callers can detect failure.
Q42.How do you check if the previous command succeeded or failed without using an if statement?
if statement?Use the special variable $? or short-circuit operators && and ||, which branch on the previous command's exit status without an explicit if.
$? holds the last exit code: 0 means success, non-zero means failure; capture it immediately because the next command overwrites it.
&& runs the next command only on success: cmd && echo ok runs the echo only if cmd returned 0.
|| runs the next command only on failure: cmd || echo failed runs the echo only if cmd returned non-zero.
Combine them for inline branching: cmd && on_success || on_failure, though be careful: if on_success fails, the || branch also runs.
Q43.Explain how set -x works and when you would use it during development.
set -x works and when you would use it during development.set -x turns on execution tracing: Bash prints each command (after expansion) to stderr before running it, which makes it the primary tool for debugging script flow.
What it shows: Each expanded command prefixed by the PS4 variable (default +), so you see variable values and substitutions after expansion.
How to scope it: Turn on with set -x and off with set +x to trace only a suspect section instead of the whole script.
When to use it: During development to see why a branch was taken, what a variable expanded to, or which command failed.
Make it more useful: Customize PS4 to add line numbers, e.g. PS4='+${LINENO}: '.
Caution: Tracing can leak secrets to logs, so disable it around sensitive values.
Q44.Explain the conceptual difference between a 'Hard Link' and a 'Soft (Symbolic) Link'. What happens to each if the original file is deleted?
A hard link is a second directory entry pointing to the exact same inode (the actual file data), while a soft link is a separate small file that stores a path pointing to the target by name.
Hard link:
Shares the same inode number, so it is indistinguishable from the original: both are equal names for one file.
Cannot cross filesystems and normally can't link directories.
Deleting the original just decrements the inode's link count; the data survives as long as one hard link remains.
Soft (symbolic) link:
Has its own inode and stores a path string; resolving it follows that path.
Can cross filesystems and point to directories.
If the original is deleted, the symlink becomes a dangling (broken) link that fails to resolve.
Create them: ln target hardlink for hard, ln -s target symlink for soft.
Q45.What is the 'umask', and how does it determine the default permissions of a newly created file?
umask', and how does it determine the default permissions of a newly created file?The umask is a per-process mask that subtracts permission bits from the default base when files and directories are created, so it controls what permissions are NOT granted by default.
It masks, it does not set:
The system base is 666 for files and 777 for directories; the umask bits are cleared from that base.
Files never get the execute bit by default (base is 666, not 777).
Computation:
Effective permission = base AND NOT umask (logical, not plain subtraction).
With umask 022: files become 644 and directories 755.
Setting and viewing:
Run umask to view, umask 027 to set; it is inherited by child processes.
Put it in shell startup files to make it persistent for a user.
Q46.What is the difference between cp, scp, and rsync for moving files?
cp, scp, and rsync for moving files?All three copy files, but cp is local-only, scp copies over SSH, and rsync copies (local or remote) efficiently by transferring only differences.
cp:
Copies within the same machine's filesystem; no networking.
Use -r for directories, -p to preserve metadata.
scp:
Copies over SSH to/from a remote host: scp file user@host:/path.
Simple but always transfers the whole file; considered legacy.
rsync:
Transfers only changed blocks via its delta algorithm, ideal for re-syncing large trees.
Can resume, preserve attributes, delete extras, and run over SSH: rsync -avz src/ user@host:/dst/.
Rule of thumb: local one-off use cp; repeated or large remote syncs use rsync.
Q47.What is the difference between 'Globbing' and 'Regular Expressions' in a shell context?
Globbing is the shell's filename-expansion pattern matching done before a command runs, while regular expressions are a richer text-matching language used by tools like grep, sed, and awk. The same symbols mean different things in each.
Globbing (by the shell):
Expands patterns into matching filenames before the command sees its arguments.
`*` = any string, `?` = one char, `[abc]` = a char class; limited vocabulary.
Regular expressions (by tools):
Match patterns within text content, not filenames.
`*` means zero-or-more of the previous atom, `.` is any char, plus anchors, quantifiers, groups.
Key trap: *.txt as a glob matches files; as a regex it is almost meaningless.
Quote patterns (grep '^a.*z$') so the shell does not glob them before the tool gets them.
Q48.Explain the difference between the = and == operators in Bash.
= and == operators in Bash.In Bash, = is used both for variable assignment and for string comparison in [ ], while == is a comparison operator valid mainly inside [[ ]]. They overlap, so context matters.
Assignment: `name=value` must have no spaces around =; == is never used to assign.
In single-bracket [ ] (POSIX test): Use = for string equality; == works in Bash but is non-portable.
In double-bracket [[ ]]: Both = and == compare strings, and the right side becomes a pattern (e.g. [[ $x == a* ]]).
Always quote and space correctly: [ "$a" = "$b" ] needs spaces around the operator.
Q49.What is the difference between shell built-in commands and external commands? How can you tell which one a command is?
Built-ins are commands implemented inside the shell itself, while external commands are separate executable files found on disk via $PATH. Built-ins run without spawning a new process, so they are faster and can affect the current shell's state.
Built-in commands:
Part of Bash itself (e.g. cd, echo, export, read).
Some must be built-in because they change the shell state: cd can't be external since a child process couldn't change the parent's directory.
External commands: Standalone programs on disk (e.g. /bin/ls, grep, awk) run in a forked child process.
How to tell them apart:
Use type commandname: reports "shell builtin", a file path, an alias, or a function.
command -V gives a verbose version; which only finds external files in $PATH.
Q50.How do functions return values in Bash, and what is the difference between 'return' and 'echo' for returning data?
return' and 'echo' for returning data?Bash functions don't return arbitrary values like other languages: return only sets an exit status (0-255), while echo (captured via command substitution) is how you pass back actual data such as strings or numbers.
return sets exit status:
An integer 0-255 only; 0 means success, non-zero means failure.
Read it via $? right after the call; use it for success/failure signaling, not data.
echo returns data:
Print the result and capture it with command substitution: result=$(myfunc).
This is the idiomatic way to return strings, lists, or large numbers.
Trap to avoid: Don't echo debug output in a function whose stdout you capture: it pollutes the returned value. Send diagnostics to stderr (>&2).
Q51.What does the 'shift' command do, and when would you use it when processing arguments?
shift' command do, and when would you use it when processing arguments?shift discards the first positional parameter (or the first N) and renumbers the rest, so $2 becomes $1, and so on. It's used to walk through arguments one at a time, especially in argument-parsing loops.
What it does: shift drops one argument; shift 2 drops two. $# decreases accordingly.
Common use cases:
Looping over flags: consume a flag, then shift to inspect the next.
Consuming a flag plus its value (shift 2) in a manual parser.
Separating known options from the remaining "rest" arguments still left in $@.
Q52.Explain what 'getopts' is used for and why it is preferred over manually parsing arguments.
getopts' is used for and why it is preferred over manually parsing arguments.getopts is a Bash built-in for parsing short command-line options (like -a or -f file) in a standard, robust way. It's preferred over hand-rolled parsing because it handles grouping, option arguments, and errors consistently.
How it works:
You give it an option string; a trailing : after a letter means that option takes an argument, exposed in $OPTARG.
It loops one option per call, tracking position with $OPTIND.
Why prefer it over manual parsing:
Correctly handles combined flags (-abc) and -fvalue forms.
Built-in error reporting for unknown options or missing arguments.
Standard, portable, and far less buggy than custom case/shift loops.
Limitation: getopts handles only short options; long options (--file) need GNU getopt or manual handling.
Q53.How does Bash perform arithmetic, and what is the difference between $(( )), let, and expr?
$(( )), let, and expr?Bash does integer arithmetic in several ways, but $(( )) (arithmetic expansion) is the modern, preferred method: it's a built-in, needs no external process, and supports C-style operators. let is an older built-in equivalent, and expr is a slow external command kept for legacy/POSIX use.
$(( )) arithmetic expansion:
Evaluates and substitutes a result: x=$((a + b * 2)).
No $ needed on variables inside, and whitespace is free; cleanest and fastest.
let built-in: Evaluates an expression for its side effect: let "x = a + 1". Works but is more error-prone with quoting.
expr external command: Spawns a process: x=$(expr $a + 1). Requires spaces around operators and escaping \*. Slow; avoid in new scripts.
Note: all three are integer-only; for floats use bc or awk.
Q54.What is the difference between a parent shell and a subshell? How do changes in a subshell affect the parent?
The parent shell is the process that spawns the subshell; the subshell receives a copy of the parent's environment, so anything it changes lives and dies with that child and is invisible to the parent.
Inheritance is one-directional:
Subshell gets copies of variables, functions, and the working directory from the parent.
Modifications (variable assignments, cd, export) affect only the subshell's copy.
What the parent does NOT see: Changed variable values, new exports, directory changes, or modified shell options after the subshell exits.
What CAN cross back: The exit status ($?) and any output written to stdout/stderr or files.
To affect the parent, stay in it: Use source / . to run a script in the current shell, or capture output: dir=$(pwd).
Q55.What is a zombie process, and can you kill it?
kill it?A zombie (defunct) process is one that has finished executing but whose entry remains in the process table because its parent hasn't yet read its exit status. You cannot kill a zombie: it is already dead, with no code running to terminate.
Why it exists: The kernel keeps a minimal entry so the parent can retrieve the exit code via wait(); it is shown as Z or <defunct> in ps.
Why you can't kill it: It uses no CPU or memory beyond the table slot; kill -9 does nothing because there's no process to signal.
How to clear it:
The parent must call wait() to reap it.
If the parent is buggy, kill the parent; the zombie is reparented to init/systemd, which reaps it automatically.
Concern: many accumulating zombies can exhaust PIDs, signaling a parent that isn't reaping children.
Q56.What is the difference between a process and a thread?
A process is an independent program in execution with its own isolated memory space; a thread is a lighter unit of execution that lives inside a process and shares that process's memory with sibling threads.
Memory and isolation:
Processes have separate address spaces; a crash in one doesn't directly corrupt another.
Threads share the process's heap, globals, and file descriptors, so they can communicate cheaply but can corrupt shared state (need locks).
Cost: Creating/switching processes is heavier; threads are cheaper to create and context-switch.
Communication: Processes need IPC (pipes, sockets, shared memory); threads just read/write shared variables.
In the shell context: Bash works almost entirely with processes (fork/exec); each command and subshell is a separate process, not a thread.
Q57.Explain the difference between running a command with & (background) vs. using nohup.
& (background) vs. using nohup.Both let a command keep running while you do other things, but & only backgrounds the job within the current shell session, whereas nohup detaches it from the controlling terminal so it survives logout and hangup signals.
& (background):
Runs the job asynchronously and returns the prompt; the job is still a child of the shell.
When the terminal closes, the shell sends SIGHUP and the job usually dies (unless disown or huponexit settings intervene).
nohup:
Makes the command ignore SIGHUP, so it keeps running after the session ends.
Redirects output to nohup.out by default if stdout is a terminal.
By itself it runs in the foreground; combine with & to both detach and background.
Typical robust form: Use nohup cmd & together, or disown an existing background job; for true detachment consider setsid, tmux, or systemd.
Q58.What is the difference between ps -ef and ps -aux? When would you prefer one over the other?
ps -ef and ps -aux? When would you prefer one over the other?They list the same processes but use different option syntaxes and default columns: ps -ef is UNIX-style (System V), while ps aux is BSD-style. Both show all processes; the choice is about which columns you want.
ps -ef:
UNIX options; shows PPID (parent PID), which makes it good for tracing process hierarchy.
Shows the full command but no CPU/memory percentages by default.
ps aux:
BSD options (note: no dash); shows %CPU, %MEM, VSZ, RSS, and process state.
Better for spotting resource hogs.
When to prefer which:
Use ps -ef to see parent/child relationships or for portable scripting across UNIX systems.
Use ps aux when investigating CPU/memory usage.
Q59.What is the 'wait' command used for in a Bash script that runs background jobs?
wait' command used for in a Bash script that runs background jobs?wait pauses the script until background jobs finish, letting you synchronize after launching work with &. It is how you turn fire-and-forget parallelism back into ordered, dependable flow.
Forms of the command:
wait with no args: block until ALL background jobs complete.
wait <PID> or wait %1: block for a specific process/job.
wait -n: return as soon as any one job finishes (Bash 4.3+).
Exit status:
wait <PID> returns that job's exit code, so you can check whether each parallel task succeeded.
This is how you collect results and fail the script if any worker failed.
Why it matters: without wait, the script would exit (or proceed) while children are still running, losing exit codes and possibly orphaning work.
Q60.What is job control in Bash, and what do the commands jobs, fg, and bg do?
jobs, fg, and bg do?Job control is the shell feature that lets you run, suspend, and resume multiple commands within a single interactive session, treating each pipeline as a "job" you can move between foreground and background. jobs, fg, and bg are the controls.
jobs: Lists the shell's current jobs with their job numbers (%1, %2) and states (Running, Stopped).
fg: Brings a job to the foreground so it holds the terminal: fg %1.
bg: Resumes a stopped job in the background so the prompt stays free: bg %1.
Workflow glue:
Ctrl+Z sends SIGTSTP to suspend the foreground job; Ctrl+C sends SIGINT to kill it.
Mostly an interactive feature: it is disabled by default in non-interactive scripts.
Q61.What are the primary disadvantages of using Bash for large-scale application logic?
Bash is excellent as glue for orchestrating commands, but it scales poorly as a real programming language: weak data structures, fragile error handling, and poor performance make large application logic painful and bug-prone.
Weak data handling:
Everything is essentially a string; no real types, objects, or nested structures.
Arrays are clumsy and associative arrays need Bash 4+; passing complex data between functions is awkward.
Fragile quoting and error handling:
Unquoted variables undergo word splitting and globbing, causing subtle bugs; you need set -euo pipefail just to get sane failure behavior.
No exceptions or stack traces; you manually check $? everywhere.
Performance: Heavy use of external commands forks many processes; loops over large data are far slower than in Python/Go.
Maintainability and tooling:
No namespaces/modules, limited testing frameworks, no native libraries for JSON/HTTP (you shell out to jq, curl).
Portability differs across shells/OSes (Bash vs POSIX sh, GNU vs BSD utilities).
Rule of thumb: when a script grows past a few hundred lines or needs structured data, switch to a general-purpose language.
Q62.What is a signal in Linux, and how does a Bash script handle it?
A signal is an asynchronous software interrupt the kernel delivers to a process to notify it of an event (e.g. user pressed Ctrl-C, a timer fired, another process asked it to stop). A Bash script can catch most signals with trap and run custom code instead of the default action.
Common signals:
SIGINT (2): Ctrl-C interrupt.
SIGTERM (15): polite request to terminate (default kill).
SIGKILL (9) and SIGSTOP: cannot be caught, blocked, or ignored.
SIGHUP (1): terminal hangup; SIGCHLD: a child changed state.
Default disposition: Each signal has a default action (terminate, stop, or ignore) unless the process installs a handler.
How Bash handles them:
trap 'handler' SIGINT installs a handler; the handler runs at a safe point between commands.
Send signals with kill -SIGTERM PID or kill -9 PID.
By convention scripts exit with code 128 + signal number (e.g. 130 for SIGINT).
Q63.Explain the conceptual difference between cut and awk. When is awk the better choice?
cut and awk. When is awk the better choice?cut is a simple field/column extractor; awk is a full text-processing language. Reach for awk whenever you need logic, computation, or flexible field handling beyond pulling out fixed columns.
cut: fast and minimal:
Selects bytes, characters, or fields by a single-character delimiter (cut -d',' -f1,3).
Cannot handle repeated/whitespace delimiters well, can't reorder fields, no conditions or math.
awk: a programming language for records and fields:
Splits each line into fields $1..$NF; default delimiter collapses runs of whitespace.
Supports patterns, conditionals, arithmetic, variables, BEGIN/END blocks, and aggregation.
awk is the better choice when you need to:
Filter rows by a condition, reorder/reformat columns, or compute sums/averages.
Handle inconsistent whitespace or multi-character separators.
Rule: fixed columns by one delimiter, use cut; anything conditional or computed, use awk.
Q64.What is the difference between the special variables $$, $!, and $?
$$, $!, and $?All three are special parameters set automatically by Bash: $$ is the current shell's PID, $! is the PID of the most recent background job, and $? is the exit status of the last completed command.
$$ - process ID of the current shell:
Commonly used to build unique temp names like /tmp/work.$$.
Inside a subshell it still expands to the parent shell's PID; use $BASHPID for the actual subshell.
$! - PID of the last backgrounded process: Set after cmd &; lets you wait "$!" or kill "$!".
$? - exit status of the last foreground command: 0 means success, non-zero means failure; capture it immediately since the next command overwrites it.
Q65.What is the difference between grep, sed, and awk, and when would you reach for each?
grep, sed, and awk, and when would you reach for each?They are three classic text tools of increasing power: grep searches for lines matching a pattern, sed performs stream edits (mainly substitutions) on lines, and awk is a field-aware programming language for extracting and transforming columnar data.
grep: find lines:
Prints (or counts/inverts) lines matching a regex: grep -i 'error' log.
Reach for it when you only need to match or filter, not modify.
sed: edit a stream:
Line-oriented transformations, most often substitution (sed 's/old/new/g'), deletion, or in-place edits.
Reach for it for find-and-replace and simple line surgery.
awk: process fields and records:
Splits lines into fields, supports conditions, math, and aggregation across rows.
Reach for it for column extraction, reporting, and computed output.
Quick rule: Match a pattern, use grep; substitute text, use sed; work with columns or do calculations, use awk. They are often piped together.
Q66.What is the difference between 'kill' and 'kill -9'? Why is SIGKILL considered a last resort?
kill' and 'kill -9'? Why is SIGKILL considered a last resort?Q67.Walk me through the order of shell expansions (e.g., brace expansion, parameter expansion, globbing). Why does the order matter?
Q68.What is the difference between Command Substitution $( ) and Process Substitution <( )? Provide a scenario where you must use the latter.
$( ) and Process Substitution <( )? Provide a scenario where you must use the latter.Q69.Explain Parameter Expansion (e.g., ${var:-default} or ${var%/*}). Why is it more efficient than calling external tools like sed or basename?
${var:-default} or ${var%/*}). Why is it more efficient than calling external tools like sed or basename?Q70.Explain the difference between quoted and unquoted patterns in [[ $string == pattern* ]].
[[ $string == pattern* ]].Q71.What is the null command ':' (colon) in Bash, and what are some practical uses for it?
':' (colon) in Bash, and what are some practical uses for it?Q72.How does Bash handle file descriptors beyond 0, 1, and 2? Explain a use case for creating a custom file descriptor.
0, 1, and 2? Explain a use case for creating a custom file descriptor.Q73.What is the difference between 2>&1 >file and >file 2>&1? Why does the order of redirection matter?
2>&1 >file and >file 2>&1? Why does the order of redirection matter?Q74.What does 'set -o noclobber' do, and how does it relate to redirection?
set -o noclobber' do, and how does it relate to redirection?Q75.What are the trade-offs of using set -e vs. manually checking $? after every command?
set -e vs. manually checking $? after every command?Q76.What is the difference between using set -e and using a trap for cleanup on failure?
set -e and using a trap for cleanup on failure?Q77.Explain the 'SUID' (Set User ID) bit on an executable. What are the security risks associated with it?
Q78.What is an Inode, and what happens if a system runs out of them?
Q79.What is the difference between the 'source' (or '.') command and the 'exec' command?
source' (or '.') command and the 'exec' command?Q80.Explain the Lastpipe behavior. Why might a variable modified inside a while loop that is part of a pipeline be lost once the loop finishes?
Lastpipe behavior. Why might a variable modified inside a while loop that is part of a pipeline be lost once the loop finishes?Q81.Do you have a favorite syscall? Explain how it works.
Q82.What is a 'Zombie Process' in the context of shell execution, and how does it differ from an 'Orphan Process'?
Q83.How do you handle 'Concurrency' in Bash, and what are the limitations compared to thread-based languages?
Q84.What is a 'zombie process' in a Unix-like system, and how does it relate to the wait() system call?
wait() system call?Q85.When would you choose to write a tool in Bash versus a higher-level language like Python or Go? What are the specific architectural tradeoffs?
Q86.What are the security risks of using eval in a Bash script, and how can they be mitigated?
eval in a Bash script, and how can they be mitigated?Q87.What happens internally when you execute a command? Explain the PATH lookup and command precedence (Alias > Built-in > Function > External).
PATH lookup and command precedence (Alias > Built-in > Function > External).Q88.Explain how the trap command works. How would you use it to ensure a script cleans up temporary files even if it receives a SIGINT or SIGTERM?
trap command works. How would you use it to ensure a script cleans up temporary files even if it receives a SIGINT or SIGTERM?Q89.Explain the difference between 'Piping' (|) and 'Process Substitution' (<(...)). When would you use one over the other?
|) and 'Process Substitution' (<(...)). When would you use one over the other?