Use um loop while:
while
read -r -p "Yes or no? " response &&
[[ $response =~ ^([yY][eE][sS]|[yY])$ ]]
do
...
done
Ou para tornar esse código POSIX sh compatible, para que você não precise ter bash instalado:
while
printf 'Yes or No? ' &&
read answer
do
case $answer in
([yY][eE][sS] | [yY]) ...;;
(*) break;;
esac
done
Observe que também verificamos um status de saída com falha de printf (que poderia sinalizar um cano quebrado) e read (que sinalizaria eof) como condições de saída do loop, como geralmente é o que você deseja.
No caso de bash ' read -p , o prompt será emitido pelo processo do shell, pois read é interno, portanto, o shell será eliminado quando o stdout se tornar um cano quebrado, mas por printf , se o shell ou apenas printf será eliminado dependerá da implementação de sh , pois nem todas as implementações têm printf incorporado. Talvez você também queira relatar o erro printf como um erro do seu script para ter consistência:
while
printf 'Yes or No? ' || exit # with the exit status of printf
read answer # eof not considered as an error condition
do
case $answer in
([yY][eE][sS] | [yY]) ...;;
(*) break;;
esac
done