Debugging with PS4 in Bash Scripting - Time & Space Complexity
When we use PS4 for debugging in bash scripts, we add extra commands that run before each executed line.
We want to see how this affects the script's running time as the script grows.
Analyze the time complexity of this bash script with PS4 debugging enabled.
#!/bin/bash
PS4='+ $BASH_SOURCE:$LINENO:${FUNCNAME[0]}: '
set -x
n=${1:-10}
for ((i=1; i<=n; i++)); do
echo "Number $i"
done
This script prints numbers from 1 to n, showing debugging info before each command.
Look for loops or repeated commands that run many times.
- Primary operation: The for-loop runs the echo command n times.
- How many times: Exactly n times, once per loop iteration.
Each loop iteration runs echo plus the PS4 debug print before it.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | About 10 echo + 10 debug prints = 20 operations |
| 100 | About 100 echo + 100 debug prints = 200 operations |
| 1000 | About 1000 echo + 1000 debug prints = 2000 operations |
Pattern observation: The total steps grow roughly twice as fast as n because of debugging output.
Time Complexity: O(n)
This means the script's running time grows directly with the number of loop steps, even with debugging on.
[X] Wrong: "Adding PS4 debugging makes the script run in quadratic time because it prints extra info."
[OK] Correct: The debug print happens once per command, so it adds a constant factor, not a new loop inside the loop.
Understanding how debugging tools affect script speed helps you write efficient scripts and explain your choices clearly.
"What if the script had nested loops with PS4 debugging enabled? How would the time complexity change?"
Practice
PS4 variable control in a bash script when debugging?Solution
Step 1: Understand the role of PS4 in bash debugging
PS4 sets the prefix string that appears before each command when debugging withset -xis active.Step 2: Differentiate PS4 from other debugging settings
PS4 does not control output files, timeouts, or command counts; it only changes the debug output prefix.Final Answer:
The prefix shown before each command when debugging is enabled -> Option DQuick Check:
PS4 = debug output prefix [OK]
- Confusing PS4 with output file settings
- Thinking PS4 controls debug duration
- Assuming PS4 limits number of debug commands
Solution
Step 1: Understand variable expansion in PS4
To show the current line number dynamically, you must escape the dollar sign in PS4 so it expands at runtime, not when assigned.Step 2: Identify correct escaping
UsingPS4='Line \$LINENO: 'escapes the dollar sign, so$LINENOexpands during debugging, showing the actual line number.Final Answer:
PS4='Line \$LINENO: ' -> Option AQuick Check:
Escape $ for runtime expansion in PS4 [OK]
- Not escaping $ causes literal $LINENO output
- Using \n instead of $LINENO for line number
- Placing newline characters incorrectly
PS4='+ $BASH_SOURCE:$LINENO:' set -x x=5 y=10 z=$((x + y)) set +x
What is the first debug output line shown after
set -x?Solution
Step 1: Analyze PS4 value and variable expansion
PS4 is set to '+ $BASH_SOURCE:$LINENO:' but $BASH_SOURCE and $LINENO are not escaped, so they expand immediately when assigned, likely empty or current shell values.Step 2: Determine actual debug prefix
Because variables are not escaped, $BASH_SOURCE is empty and $LINENO is 2 (line ofset -x), so prefix becomes '+ :2:'.Final Answer:
+ :2: x=5 -> Option CQuick Check:
Unescaped vars expand early, prefix = '+ :2:' [OK]
- Assuming $BASH_SOURCE expands to script filename
- Expecting line number to be dynamic without escaping
- Ignoring immediate expansion on assignment
PS4='Line $LINENO: ' set -x foo=bar set +x
But the debug output shows
Line $LINENO: foo=bar literally. What is the fix?Solution
Step 1: Identify why $LINENO is literal
Using single quotes with unescaped $LINENO causes it to be treated as literal text, not expanded during debugging.Step 2: Fix by escaping $ for runtime expansion
Escaping $ as \$ in PS4 delays expansion until debugging runs, showing actual line numbers.Final Answer:
Change PS4 to 'Line \$LINENO: ' to delay variable expansion -> Option AQuick Check:
Escape $ in PS4 to expand at debug time [OK]
- Not escaping $ in PS4
- Changing quotes incorrectly
- Setting PS4 after enabling debugging
Solution
Step 1: Understand variable expansion timing in PS4
To show dynamic info like filename, line number, and function name during debugging, variables must be escaped with backslashes to delay expansion until debug time.Step 2: Choose correct syntax for array variable FUNCNAME
Use\${FUNCNAME[0]}to get current function name properly escaped.Step 3: Verify full PS4 string
PS4='+ \${BASH_SOURCE}:\${LINENO}:\${FUNCNAME[0]}: ' correctly escapes all variables and uses braces for array indexing, ensuring dynamic debug info appears.Final Answer:
PS4='+ \${BASH_SOURCE}:\${LINENO}:\${FUNCNAME[0]}: ' -> Option BQuick Check:
Escape all vars with braces for dynamic debug info [OK]
- Not escaping variables causing static output
- Missing braces for array FUNCNAME
- Using $FUNCNAME without index for function name
Ready to prove it?
Pass the test and this pattern moves unknown
