while loop to read file ends prematurely

If you run commands which read from stdin (such as ssh) inside a loop, you need to ensure that either:

  • Your loop isn’t iterating over stdin
  • Your command has had its stdin redirected:

…otherwise, the command can consume input intended for the loop, causing it to end.

The former:

while read -u 5 -r hostname; do
  ssh "$hostname" ...
done 5<file

…which, using bash 4.1 or newer, can be rewritten with automatic file descriptor assignment as so:

while read -u "$file_fd" -r hostname; do
  ssh "$hostname" ...
done {file_fd}<file

The latter:

while read -r hostname; do
  ssh "$hostname" ... </dev/null
done <file

…can also, for ssh alone, can also be approximated with the -n parameter (which also redirects stdin from /dev/null):

while read -r hostname; do
  ssh -n "$hostname"
done <file

Leave a Comment