Reputation: 51
CONFIRM=""
echo "Do you want to backup your home directory? Please enter y|Y or n|N"
read CONFIRM;
if [[ "$CONFIRM" != "Y" ]] || [[ "$CONFIRM" != "y" ]]; then
echo "The backup will not run. Aborting now..."
else
echo "The backup will run now. Backing up to $DEST"
# more code
fi
Whenever I enter "y" or "Y", the condition under else
should be executed. Instead, the condition under if
gets executed no matter what I enter. I've tried multiple combinations of square brackets and quoting I can think of, but nothing works. Why doesn't the else
branch correctly execute?
Upvotes: 0
Views: 68
Reputation: 7327
Another example, I ensure we don't continue until we get specifically y/n/q as inputs. using -p -n1 removes the need to press enter. In summary: a case statement, reads the one keypress, lowercase checking etc ... This example allows for yes/no or quit.
typeset confirm=''
while true; do
read -p "Select (y/n/q) ?" -n1 confirm
case ${confirm,,} in
y|n|q) break;;
*) echo "Answer y for yes / n for no or q for quit.";;
esac
done
echo -e "\nAnswer = $confirm" ;sleep 2
if [[ "${confirm,,}" == "q" ]] ; then
echo "OK Quitting.."
exit 0
fi
if [[ "${confirm,,}" == "y" ]] ; then
echo "Continuing ..."
else
echo "No? Do something else etc.. "
fi
Upvotes: 0
Reputation: 1836
If we look closely at the prompt "Please enter y | Y or n | N", then there is a third case missing, that handles invalid input. Together with @cdarke's answer, this results e.g. in the following short condition:
CONFIRM=""
echo "Do you want to backup your home directory? Please enter y|Y or n|N"
read CONFIRM;
if [[ "$CONFIRM" = [Yy] ]]; then
echo "The backup will run now. Backing up to $DEST"
# more code
elif [[ "$CONFIRM" = [Nn] ]]; then
echo "The backup will not run. Aborting now..."
else
echo "Wrong Input. Please enter y|Y or n|N."
fi
Upvotes: 1
Reputation: 183371
This:
[[ "$CONFIRM" != "Y" ]] || [[ "$CONFIRM" != "y" ]]
means "$CONFIRM
isn't Y
or $CONFIRM
isn't y
". That is always guaranteed to be true:
$CONFIRM
is Y
, then it's not y
, so the second option is true$CONFIRM
is y
, then it's not Y
, so the first option is true$CONFIRM
is anything else, then both options are trueTo fix this, you need to use &&
("and") instead of ||
("or"):
[[ "$CONFIRM" != Y ]] && [[ "$CONFIRM" != y ]]
which, by De Morgan's laws, is equivalent to this:
! { [[ "$CONFIRM" = Y ]] || [[ "$CONFIRM" = y ]] ; }
Upvotes: 3