CompTIA Linux+ (XK0-006)Automation, Orchestration and ScriptingHard
A system administrator is developing a Bash script to manage user accounts. The script needs to iterate through a list of usernames provided in a file, `users.txt`, and perform an action for each user. The `users.txt` file contains one username per line. Which Bash construct is the most robust way to read each line from `users.txt` and process it within a loop, correctly handling usernames that might contain spaces?
- Awhile IFS= read -r user; do echo "Processing $user"; done < users.txt
- Bfor user in $(< users.txt); do echo "Processing $user"; done
- Ccat users.txt | while read user; do echo "Processing $user"; done
- Dfor user in $(cat users.txt); do echo "Processing $user"; done
Show answer & explanationAnswer & explanation
Correct answer: A. while IFS= read -r user; do echo "Processing $user"; done < users.txt
The `while IFS= read -r user; do ... done < users.txt` construct is the most robust for reading lines from a file in Bash. `IFS=` temporarily clears the Internal Field Separator, preventing word splitting on spaces. `-r` prevents backslash interpretation. This ensures that each line, even with spaces or special characters, is read as a single, complete value into the `user` variable.
Why the other options are wrong
- B. Similar to A, `$(< users.txt)` performs command substitution and word splitting, which will break usernames containing spaces into multiple tokens.
- C. While `cat ... | while read user` reads line by line, it still performs word splitting by default (unless `IFS` is unset). Also, pipelines create subshells, which can affect variable scope if not careful.
- D. This uses command substitution and will cause word splitting if usernames contain spaces, treating parts of a username as separate entries.
Bash `while IFS= read -r` Loop
The `while IFS= read -r line; do ... done < file` construct is the idiomatic and most robust way in Bash to read a file line by line, preserving whitespace and preventing backslash interpretation.
- `IFS=` prevents word splitting (important for lines with spaces).
- `-r` prevents backslash escapes from being interpreted.
- Redirecting input with `< file` avoids subshell issues of pipes.
Memory trick: IFS and Read, for lines you need, perfectly freed.