patternbashModerate
read builtin: safely reading user input and file lines
Viewed 0 times
readstdininputline readingIFSbackslashinteractivepasswordtimeout
Problem
Using 'read' without options or proper IFS handling causes issues: backslash interpretation mangles input, trailing whitespace is stripped, and reading with a variable name in a loop inside a pipeline creates subshell scope loss.
Solution
Always use 'read -r' to suppress backslash interpretation. Use 'IFS= read -r' to preserve leading/trailing whitespace.
# Read a line preserving all characters
IFS= read -r line
# Interactive prompt
read -rp "Enter name: " name
# Read file line by line correctly
while IFS= read -r line; do
echo "Line: $line"
done < file.txt
# Read password silently
read -rsp "Password: " password
echo
# Read with timeout
if read -rt 5 -p "Continue? [y/N] " ans; then
echo "Got: $ans"
else
echo "Timed out"
fi
# Read a line preserving all characters
IFS= read -r line
# Interactive prompt
read -rp "Enter name: " name
# Read file line by line correctly
while IFS= read -r line; do
echo "Line: $line"
done < file.txt
# Read password silently
read -rsp "Password: " password
echo
# Read with timeout
if read -rt 5 -p "Continue? [y/N] " ans; then
echo "Got: $ans"
else
echo "Timed out"
fi
Why
Without -r, read interprets backslash sequences (\n becomes newline, \t becomes tab, trailing \ continues the line). Without IFS=, leading/trailing spaces are stripped.
Gotchas
- read inside a pipeline runs in a subshell — variables set inside won't survive: 'cmd | while read ...'
- Use 'while IFS= read -r line; done < file' (redirect) not '| while read' to keep scope
- read -a ARRAY reads words into an array (bash only)
- read -d '' reads until null byte — useful with find -print0
- -t timeout: returns non-zero if timeout occurs — handle with set -e carefully
Code Snippets
read builtin usage patterns
# Process file preserving all whitespace
while IFS= read -r line; do
printf 'Got: [%s]\n' "$line"
done < /etc/hosts
# Interactive with prompt
read -rp "Enter your name: " name
echo "Hello, $name"
# Silent password input
read -rsp "Password: " pass
echo # newline after hidden input
# Read into array (splits on IFS)
read -ra words <<< "one two three"
echo "${#words[@]} words: ${words[*]}"Context
Reading user input interactively or processing file lines in bash scripts
Revisions (0)
No revisions yet.