1

I am not looking for a different way to accomplish the apparent intention. I'm looking to understand why this exact syntax is not working.

[root@lvs ~]# while true;do
> echo "Would you like the script to check the second box ([y]n)?"
> read ans
>         if [ "$ans" == "n" ];then
>                 echo
>                 echo "bye"
>                 exit
>         elif [ "$ans" != "" -o "$ans" != "y" ];then
>                 echo "Invalid entry..."
>         else
>                 break
>         fi
> done
Would you like the script to check the second box ([y]n)? **"Should have continued"**

Invalid entry...
Would you like the script to check the second box ([y]n)? **"Should have continued"**
y
Invalid entry...
Would you like the script to check the second box ([y]n)? **"Correct behavior"**
alskjfasldasdjf
Invalid entry...
Would you like the script to check the second box ([y]n)? **"Correct behavior"**
n

bye

Here's a reference that's identical to so many others i found. I understand what it's doing, it's using the non logical's for AND and OR when everything I've read said that it should be using logical bools.

http://www.groupsrv.com/linux/about140851.html

Ok so here it is, with Nahuel's suggestion behaving how I had originally expected it to:

[root@lvs ~]# while true;do
> echo "Would you like the script to check the second box ([y]n)?"
> read ans
>         if [ "$ans" = "n" ];then
>                 echo
>                 echo "bye!"
>                 exit
>         elif [ "$ans" != "" -a "$ans" != "y" ];then
>                 echo "Invalid entry..."
>         else
>                 break
>         fi
> done
Would you like the script to check the second box ([y]n)?
asdfad
Invalid entry...
Would you like the script to check the second box ([y]n)?

[root@lvs ~]# while true;do
> echo "Would you like the script to check the second box ([y]n)?"
> read ans
>         if [ "$ans" = "n" ];then
>                 echo
>                 echo "bye!"
>                 exit
>         elif [ "$ans" != "" -a "$ans" != "y" ];then
>                 echo "Invalid entry..."
>         else
>                 break
>         fi
> done
Would you like the script to check the second box ([y]n)?
y
[root@lvs ~]# while true;do
> echo "Would you like the script to check the second box ([y]n)?"
> read ans
>         if [ "$ans" = "n" ];then
>                 echo
>                 echo "bye!"
>                 exit
>         elif [ "$ans" != "" -a "$ans" != "y" ];then
>                 echo "Invalid entry..."
>         else
>                 break
>         fi
> done
Would you like the script to check the second box ([y]n)?
n

logout
1
  • BTW, == is a bug that is sadly accepted by bash. Only = is the POSIX way to test for equality. Commented Sep 21, 2012 at 9:25

3 Answers 3

1

The problem is that : [ "$ans" != "" -o "$ans" != "y" ] is always true because of the or and the negation. $ans cannot be equal to "" and to "y".

Try replace these lines

if [ "$ans" == "n" ];then 
elif [ "$ans" != "" -o "$ans" != "y" ];then 

by these

if [ "$ans" = "n" ];then 
elif [ "$ans" != "" -a "$ans" != "y" ];then 

or these

if [[ $ans == n ]];then 
elif [[ $ans != "" && $ans != y ]];then 

The easier is to do is a case:

case $ans in
  y) echo "yes"
  ;;
  n) echo "no"
  ;;
  *)
  ;;
 esac

also break must be used only in a for or while loop, or in a select but it is missing in your post .

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for the quick responses everyone. The -o example that I used in my post was just one of what seemed like 95858943737495048 woefully futile attempts. I just tried Nahuel's suggestion above and by god IT WORKED!! Now I just need to unerstand. My logic was as follows:
My logic was as follows: Ask question ([y],n) and devise the most efficent method for correctly handling any type of possible user input. So, if the user presses "n" - exit the scritp If the user presses something like "vi45 08noisdfgoh qer g08haergrh8" display error and prompt for retry. 3. 1 and 2 leave y and "" as the only remaining keystrokes
What I still don't understand is why there dosnt seem to be anyway for an "OR" to truly work with strings in bash...Why is that?
For example, the tcpdump below has a conditional filter to capture udp broadcast's sourced from port boopc [OR || -o] tcp unicasts destined for tcp port 57000...and it works just find: [root@lvs1 ~]# tcpdump udp src port bootps or tcp dst port 57000 tcpdump: verbose output suppressed listening on eth0, link-type EN10MB (Ethernet), capture size 96 bytes 08:05:13.145024 IP dc1.x.net.bootps > 255.255.255.255.bootpc: BOOTP/DHCP, Reply, length: 300 08:05:32.099530 IP precision.x.net.14044 > lvs1.x.net.57000: S 444213637:444213637(0) win 8192 <mss 1460,nop,wscale 8,nop,nop,sackOK>
there is no problem with or and strings for example [ "$ans" != "" -a "$ans" != "y" ] is equivalent to [ \! \( "$ans" = "" -o "$ans" = "y" \) ] the problem is the -o with !=
|
0

I don't really understand, why do you use -o in the elif. I would use "||" or "OR" operator. When you use two conditions in if, you should use double [[ and ]]. So if you use:

    elif [[ "$ans" != "" ||  "$ans" != "y" ]];then 

it works fine.

1 Comment

[ "$ans" != "" -o "$ans" != "y" ] is always true
0

also logically its a flawed way of doing things. firstly using case would be best in this scenario, secondly you are looking for == n then stating if it is blank or not equal to yes - so although no is caught out in first if statement in theory it would still meet second criteria

surely the most logical way to ensure input is 100% would be

 if [ "$ans" == "n" ];then
                 echo
                 echo "bye"
                 exit
         elif [ "$ans" == "y" ];then
                 echo Yes
                        break;

        else

                 echo "Invalid entry... >$ans<"
         fi

3 Comments

Please don't proliferate the == bug. The only way to properly test for equality is =.
My logic was as follows: Ask question ([y],n) and devise the most efficent method for correctly handling any type of possible user input. So: 1. If the user presses "n" - exit the scritp 2. If the user presses something like "vi45 08noisdfgoh qer g08haergrh8" display error and prompt for retry. 3. 1 and 2 leave y and "" as the only remaining keystrokes How is this flawed?
its flawed because you are looking for a yes no and yet you seem to be processing the anything else before yes as above example it processes yes/no then anything else- the above example i given you is not any different to using a case statement of n) something y) something *) error

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.