You can use process substitution if you're on a shell that supports it (e.g., bash, ksh, or zsh):
while read sid p_name p_age ; do ...; done < <(get_names)
This is required in bash if you want the final link of your pipeline to be your running shell (so that it may have an effect on your running shell):
for sh in bash ksh zsh; do
echo $sh:; $sh -c 'while read var; do i=$var
done < <(printf "%s\n" 1 2); echo $i '
done
Output:
bash:
2
ksh:
2
zsh:
2
Whereas with a regular pipeline:
for sh in bash ksh zsh; do
echo $sh:; $sh -c 'printf "%s\n" 1 2 |
while read var; do i=$var; done ; echo $i ';
done
the assignment doesn't stick because bash runs the while loop in a subshell rather than the current shell:
bash:
ksh:
2
zsh:
2