The following bash script reads a string from the user and tests whether the string fulfills the criteria for a hostname that you seem to want to enforce.
The first of the two patterns used in the case statement tests for the pathological case of two dots with no characters in-between (this is a pattern that we don't act upon). We test for a string containing at least two dots and no dot at either end with the second pattern. The hostname variable fdqn is set to the string only if this second pattern matches the string. Note that the string foo..bar matches the second pattern, which is why we preemptively match the double dot substring with the first pattern.
#!/bin/bash
unset -v count fdqn
while true; do
read -p 'Enter hostname: ' -r
case $REPLY in (*..*) ;; ([!.]*.*.*[!.]) fdqn=$REPLY; break; esac
echo 'Invalid format' >&2
count=$(( count + 1 ))
[ "$count" -eq 2 ] && break
done
if [ -z "$fdqn" ]; then
echo 'No valid hostname entered' >&2
exit 1
fi
printf 'The hostname is "%s"\n' "$fdqn"
The count variable keeps track of how many times the user has tried to enter a string. We break out of the loop if this variable's value reaches two.
There is no real need to use a case statement here unless you want to make it a portable sh script (in which case you would have to do the read statement differently). With the globbing operator == in bash, the case statement would be written like below.
if [[ $REPLY == *..* ]]; then
:
elif [[ $REPLY == [!.]*.*.*[!.] ]]; then
fdqn=$REPLY
break
fi
The two tests could also be joined using && if the first is negated.
if [[ $REPLY != *..* ]] && [[ $REPLY == [!.]*.*.*[!.] ]]; then
fdqn=$REPLY
break
fi
If you want to avoid getting hostnames containing three dots, then make sure that $REPLY does not match *.*.*.*, just like it shouldn't match *..*.