Если скрипт должен работать в разных shell, выбирайте while read. Если это именно Bash, mapfile делает код компактнее и проще для чтения.

Переносимый цикл

while IFS= read -r line; do
  printf 'row=%s\n' "$line"
done < file.txt

Bash-вариант

#!/usr/bin/env bash
set -euo pipefail

mapfile -t lines < file.txt
printf 'rows=%s\n' "${#lines[@]}"
  • IFS= сохраняет пробелы в начале и конце строки.
  • -r помогает читать обратные слеши как данные.
  • mapfile -t убирает перевод строки и складывает файл в массив.
  • #!/usr/bin/env bash фиксирует ожидаемый интерпретатор через $PATH.