Reputation: 2410
I have the following code :
#!/bin/ksh
echo "1) Option 1"
echo "2) Option 2"
echo "3) Option 3"
echo "4) Option 4"
opt=0
while [ x$opt = "x" ] || [ $opt != "1" ] || [ $opt != "2" ] || [ $opt != "3" ] || [ $opt != "4" ]; do
printf "Enter [1|2|3|4] : "
read -r opt
done
echo "Option selected : $opt
The while [ x$opt = "x" ]
means "while $opt
is empty" in case you wonder.
Here's the output :
Will:/home/will> ./script.ksh
Enter [1|2|3|4] :
Enter [1|2|3|4] : jde
Enter [1|2|3|4] : 1
Enter [1|2|3|4] : 2
Enter [1|2|3|4] : 3
Enter [1|2|3|4] : 4
Enter [1|2|3|4] :
So when typing nothing or something unexpected it loops, OK.
But why does it still loops when 1/2/3 and 4 are typed when it should prompt the last echo
message ?
EDIT :
I have added a echo $opt
in the while loop, and it prints me this :
Enter [1/2/3/4] : d
d
Enter [1/2/3/4] : 1
1
Enter [1/2/3/4] :
So $opt received the user input as it should, but the while still never breaks.
Upvotes: 1
Views: 3361
Reputation: 785761
You may want to avoid multiple if
conditions using much cleaner case
expressions:
#!/bin/ksh
echo "1) Option 1"
echo "2) Option 2"
echo "3) Option 3"
echo "4) Option 4"
while true
do
case $opt in
1|2|3|4)
break ;;
*)
printf "Enter [1|2|3|4] : "
read -r opt ;;
esac
done
echo "Option selected : $opt"
About your problem, you don't need ||
between conditions, you actually need to use &&
to check for all negative conditions:
#!/bin/ksh
echo "1) Option 1"
echo "2) Option 2"
echo "3) Option 3"
echo "4) Option 4"
opt=
while [ "x$opt" = "x" ] && [ "$opt" != "1" ] && [ "$opt" != "2" ] && [ "$opt" != "3" ] && [ "$opt" != "4" ]; do
printf "Enter [1|2|3|4] : "
read -r opt
done
echo "Option selected : $opt"
Also it is important to quote $opt
inside [ ... ]
as shown in my answer.
Upvotes: 1
Reputation: 4819
[ $opt != "1" ] || [ $opt != "2" ]
will always be true, whatever value $opt has.
Therefore, the behaviour is normal.
Upvotes: 1