Como solução alternativa, sugiro o seguinte:
#!/bin/bash
while ! su -c "foo; exit 0"; do
read -n 1 -p "Retry? (y/n) " ch
[[ "$ch" != "y" ]] && break # This does the same in fewer lines
done
Isso retorna um valor zero mesmo se foo
tiver um código de saída diferente.
AVISO: usando essa solução alternativa (que é um pouco feia), você não poderá determinar foo
do código de saída. Não sei se é necessário para o seu projeto.