Bird
Raised Fist0
Bash Scriptingscripting~15 mins

for loop (list-based) in Bash Scripting - Deep Dive

Choose your learning style10 modes available
Overview - for loop (list-based)
What is it?
A list-based for loop in Bash runs a set of commands repeatedly for each item in a list. It goes through each element one by one and executes the commands using that element. This helps automate tasks that need to be done multiple times with different inputs. The list can be a set of words, numbers, or filenames.
Why it matters
Without list-based for loops, you would have to repeat commands manually for each item, which is slow and error-prone. This loop saves time and reduces mistakes by automating repetitive tasks. It makes scripts flexible and powerful, allowing you to handle many items easily. Imagine renaming hundreds of files one by one without a loop—that would be tedious!
Where it fits
Before learning list-based for loops, you should know basic Bash commands and how to run scripts. After mastering this, you can learn more complex loops, conditional statements, and automation techniques like while loops and arrays.
Mental Model
Core Idea
A list-based for loop runs commands once for each item in a list, using the item as input each time.
Think of it like...
It's like sorting mail: you pick up each envelope from a pile and stamp it before moving to the next one, repeating the same action for every envelope.
for item in list
├─> run commands using item
├─> move to next item
└─> repeat until list ends
Build-Up - 7 Steps
1
FoundationBasic for loop syntax
🤔
Concept: Learn the simple structure of a list-based for loop in Bash.
The basic syntax is: for item in list; do commands done Here, 'item' takes each value from 'list' one by one, and the commands run using that 'item'. For example: for fruit in apple banana cherry; do echo $fruit done
Result
apple banana cherry
Understanding the simple syntax is the first step to automating repeated tasks with different inputs.
2
FoundationUsing variables inside the loop
🤔
Concept: How to use the loop variable inside commands to work with each list item.
Inside the loop, you use the variable with a $ sign to access the current item. For example: for color in red green blue; do echo "Color is $color" done This prints a message for each color in the list.
Result
Color is red Color is green Color is blue
Knowing how to use the loop variable lets you customize commands for each item dynamically.
3
IntermediateLooping over command output
🤔Before reading on: do you think you can use a for loop to process the output of a command directly? Commit to yes or no.
Concept: You can loop over the output of commands by using command substitution inside the list.
Instead of a fixed list, you can use $(command) to get a list from a command. For example: for file in $(ls *.txt); do echo "File: $file" done This loops over all .txt files in the current folder.
Result
File: notes.txt File: todo.txt File: report.txt
Using command output as a list makes loops flexible and powerful for real-world tasks like processing files.
4
IntermediateHandling spaces in list items
🤔Before reading on: do you think list items with spaces work correctly in a basic for loop? Commit to yes or no.
Concept: List items with spaces can break loops unless handled carefully with quotes or arrays.
If list items have spaces, the loop splits them incorrectly. For example: for name in "John Doe" "Jane Smith"; do echo "$name" done This prints each full name correctly because of quotes.
Result
John Doe Jane Smith
Knowing how to handle spaces prevents bugs when working with real-world data like names or file paths.
5
AdvancedUsing arrays with for loops
🤔Before reading on: do you think arrays are necessary for all list-based loops? Commit to yes or no.
Concept: Arrays store lists safely and work well with for loops, especially for complex data or items with spaces.
Declare an array: names=("John Doe" "Jane Smith" "Alice Johnson") Loop over it: for name in "${names[@]}"; do echo "$name" done This handles spaces and special characters safely.
Result
John Doe Jane Smith Alice Johnson
Using arrays avoids common splitting problems and is best practice for complex lists.
6
AdvancedNested for loops for multiple lists
🤔Before reading on: do you think you can loop over two lists at the same time with nested loops? Commit to yes or no.
Concept: You can put one for loop inside another to combine items from two lists.
Example: for color in red green; do for shape in circle square; do echo "$color $shape" done done This prints all color-shape pairs.
Result
red circle red square green circle green square
Nested loops let you explore combinations and build more complex automation.
7
ExpertPitfalls with word splitting and globbing
🤔Before reading on: do you think for loops always handle filenames with spaces correctly? Commit to yes or no.
Concept: Bash splits list items by spaces and expands wildcards, which can cause bugs if not controlled.
Example problem: for file in $(ls *.txt); do echo "$file" done If a filename has spaces, it splits incorrectly. Better to use arrays or while read loops. Safe alternative: mapfile -t files < <(ls *.txt) for file in "${files[@]}"; do echo "$file" done
Result
Correctly prints filenames even with spaces
Understanding Bash's splitting and globbing behavior is key to writing reliable loops in production.
Under the Hood
Bash reads the list after 'in' and splits it into words using spaces or newlines. For each word, it assigns the value to the loop variable and runs the commands inside the loop body. This happens sequentially until all items are processed. If the list comes from command substitution, Bash first runs the command, captures its output, then splits it into words. Quoting and arrays affect how splitting happens.
Why designed this way?
Bash was designed as a simple shell language for Unix systems, where text streams and word splitting are common. The list-based for loop fits this model by treating lists as space-separated words, making it easy to write quick scripts. Alternatives like arrays were added later for more complex needs, but the original design favors simplicity and text processing.
┌───────────────┐
│ for item in list │
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ split list by  │
│ spaces/newlines│
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ assign item    │
│ run commands   │
└───────┬───────┘
        │
        ▼
┌───────────────┐
│ repeat for all │
│ items in list  │
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Does a for loop in Bash always handle filenames with spaces correctly? Commit to yes or no.
Common Belief:For loops automatically handle filenames with spaces without extra care.
Tap to reveal reality
Reality:Bash splits list items by spaces, so filenames with spaces get split into multiple items unless quoted or handled with arrays.
Why it matters:Scripts break or behave unexpectedly when processing files with spaces, causing data loss or errors.
Quick: Can you use a for loop directly on a command's output without issues? Commit to yes or no.
Common Belief:You can safely loop over any command output using for loops without problems.
Tap to reveal reality
Reality:Command output is split by spaces and newlines, which can break items with spaces or special characters unless handled carefully.
Why it matters:This leads to bugs in scripts that process file lists or data with spaces, causing incorrect processing.
Quick: Does quoting the list in a for loop prevent word splitting? Commit to yes or no.
Common Belief:Quoting the entire list in a for loop keeps items intact and prevents splitting.
Tap to reveal reality
Reality:Quoting the whole list treats it as a single item, so the loop runs once with the entire string, not item by item.
Why it matters:This causes loops to run only once unexpectedly, breaking automation logic.
Quick: Is it always better to use for loops over while loops for list processing? Commit to yes or no.
Common Belief:For loops are always the best choice for processing lists in Bash.
Tap to reveal reality
Reality:While loops with read are safer for complex lists or filenames with spaces, avoiding word splitting issues.
Why it matters:Choosing the wrong loop type can cause subtle bugs and data corruption in scripts.
Expert Zone
1
Using arrays with "${array[@]}" preserves each item exactly, avoiding word splitting and globbing issues common in simple for loops.
2
Command substitution $(...) inside for loops can cause unexpected splitting; using mapfile or while read loops is safer for complex outputs.
3
Nested for loops can cause performance issues with large lists; sometimes combining lists or using other tools like xargs is more efficient.
When NOT to use
Avoid list-based for loops when processing filenames or data with spaces or special characters; instead, use while read loops or arrays. For very large datasets, consider tools like xargs or parallel for better performance and safety.
Production Patterns
In real scripts, experts use arrays to store lists safely, combine for loops with conditionals for filtering, and prefer while read loops for reading files line-by-line. They also handle errors and edge cases like empty lists or special characters carefully.
Connections
Array data structure
Builds-on
Understanding arrays helps manage lists safely in Bash loops, preventing common bugs with spaces and splitting.
Pipelining in Unix shells
Complementary
Combining for loops with pipelines allows powerful data processing workflows, chaining commands efficiently.
Assembly line in manufacturing
Analogy in a different field
Just like an assembly line processes each item step-by-step, a for loop processes each list item sequentially, showing how automation works across domains.
Common Pitfalls
#1Loop breaks when list items have spaces
Wrong approach:for file in $(ls *.txt); do echo "$file" done
Correct approach:mapfile -t files < <(ls *.txt) for file in "${files[@]}"; do echo "$file" done
Root cause:Using command substitution splits output by spaces, breaking filenames with spaces.
#2Loop runs only once due to quoting whole list
Wrong approach:for item in "apple banana cherry"; do echo "$item" done
Correct approach:for item in apple banana cherry; do echo "$item" done
Root cause:Quoting the entire list treats it as a single string, not separate items.
#3Using for loop for reading lines from a file with spaces
Wrong approach:for line in $(cat file.txt); do echo "$line" done
Correct approach:while IFS= read -r line; do echo "$line" done < file.txt
Root cause:For loop splits input by spaces, breaking lines with spaces; while read preserves lines.
Key Takeaways
A list-based for loop runs commands once for each item in a list, automating repetitive tasks easily.
Bash splits list items by spaces, so handling spaces and special characters requires quoting or arrays.
Using arrays and while read loops helps avoid common bugs with word splitting and globbing.
Nested loops and command substitution expand the power of for loops but need careful handling.
Understanding Bash's splitting behavior is essential for writing reliable and safe automation scripts.

Practice

(1/5)
1. What does the following Bash code do?
for item in apple banana cherry; do echo $item; done
easy
A. Prints each fruit name on a new line
B. Prints all fruit names on the same line
C. Creates a list of fruits without printing
D. Causes a syntax error

Solution

  1. Step 1: Understand the for loop structure

    The loop goes through each word in the list: apple, banana, cherry.
  2. Step 2: Check the command inside the loop

    It prints each item using echo, so each fruit name appears on its own line.
  3. Final Answer:

    Prints each fruit name on a new line -> Option A
  4. Quick Check:

    Loop prints each item line by line = C [OK]
Hint: For loops print each list item one by one [OK]
Common Mistakes:
  • Thinking echo prints all items on one line
  • Confusing list iteration with variable assignment
  • Missing the do/done keywords
2. Which of these is the correct syntax for a Bash for loop over a list of words?
easy
A. loop item in apple banana cherry: echo $item
B. for (item in apple banana cherry) { echo $item }
C. for item in apple banana cherry; do echo $item; done
D. foreach item in apple banana cherry; echo $item; end

Solution

  1. Step 1: Identify valid Bash for loop syntax

    Bash uses: for variable in list; do commands; done
  2. Step 2: Compare options

    Only for item in apple banana cherry; do echo $item; done matches Bash syntax exactly; others use syntax from other languages or invalid forms.
  3. Final Answer:

    for item in apple banana cherry; do echo $item; done -> Option C
  4. Quick Check:

    Bash for loop syntax = D [OK]
Hint: Bash loops use 'for var in list; do ...; done' [OK]
Common Mistakes:
  • Using parentheses or braces like other languages
  • Using foreach or loop keywords not in Bash
  • Omitting do or done keywords
3. What is the output of this script?
for word in one two three; do echo "$word"; done
medium
A. one two three (each on its own line)
B. one\ntwo\nthree
C. one two three
D. one two three

Solution

  1. Step 1: Understand the loop iteration

    The loop runs three times, each time echoing one word: one, two, three.
  2. Step 2: Understand echo output with quotes

    Quotes preserve spaces but echo prints each word on a new line by default.
  3. Final Answer:

    one two three (each on its own line) -> Option A
  4. Quick Check:

    Echo prints each item on separate lines = A [OK]
Hint: Echo prints each loop item on its own line by default [OK]
Common Mistakes:
  • Thinking echo prints all items on one line
  • Confusing literal \n with newline
  • Ignoring quotes effect on output
4. Find the error in this Bash script:
for item apple banana cherry; do echo $item; done
medium
A. Missing semicolon after 'banana'
B. Variable name 'item' is invalid
C. Incorrect use of quotes around list items
D. Missing 'in' keyword after 'for item'

Solution

  1. Step 1: Check for loop syntax

    Bash requires 'for variable in list; do ...; done'. The 'in' keyword is missing here.
  2. Step 2: Identify the error cause

    Without 'in', Bash cannot parse the list, causing a syntax error.
  3. Final Answer:

    Missing 'in' keyword after 'for item' -> Option D
  4. Quick Check:

    For loop needs 'in' keyword = B [OK]
Hint: Always include 'in' after variable in for loops [OK]
Common Mistakes:
  • Forgetting the 'in' keyword
  • Adding unnecessary semicolons inside list
  • Misnaming variables with invalid characters
5. You want to print only the fruits that start with the letter 'b' from this list:
fruits="apple banana cherry blueberry"
for fruit in $fruits; do
  # Fill condition here
  echo "$fruit"
done

Which condition inside the loop correctly filters fruits starting with 'b'?
hard
A. if [ $fruit = 'b' ]; then
B. if [[ $fruit == b* ]]; then
C. if [[ $fruit =~ b* ]]; then
D. if [ $fruit == 'b*' ]; then

Solution

  1. Step 1: Understand string pattern matching in Bash

    Double brackets [[ ]] support pattern matching with == and wildcards like '*'.
  2. Step 2: Check each condition

    A uses [[ $fruit == b* ]] which matches strings starting with 'b'. B uses single brackets for exact 'b' match. C uses [[ $fruit =~ b* ]]; b* regex matches zero or more 'b's (including none), so every string. D uses single brackets which don't support patterns or ==.
  3. Final Answer:

    if [[ $fruit == b* ]]; then -> Option B
  4. Quick Check:

    Use [[ var == pattern* ]] for prefix match = A [OK]
Hint: Use [[ var == prefix* ]] to match string start in Bash [OK]
Common Mistakes:
  • Using single brackets with wildcard patterns
  • Confusing regex =~ with == operator
  • Comparing to exact string 'b' instead of prefix
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard