Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I want to try simple script

flag=false
while !$flag
do
   read x
   if [ "$x" -eq "true" ]
   then
     flag=true
   fi
   echo "${x} : ${flag}"
done

But when i run it, if i type true, i will see that x="true" and flag="true", but the cycle doesn't end. What is wrong with script? How to proper invert boolean variable?

share|improve this question
1  
See stackoverflow.com/questions/8108249/… –  ata Nov 12 '11 at 23:19
    
thx! i got it now –  user253202 Nov 13 '11 at 8:48

2 Answers 2

up vote 8 down vote accepted

There are two errors in your script. The first is that you need a space between ! and $flag, otherwise the shell looks for a command called !$flag. The second error is that -eq is for integer comparisons, but you're using it on a string. Depending on your shell, either you'll see an error message and the loop will continue forever because the condition [ "$x" -eq "true" ] cannot be true, or every non-integer value will be treated as 0 and the loop will exit if you enter any string (including false) other than a number different from 0.

While ! $flag is correct, it's a bad idea to treat a string as a command. It would work, but it would be very sensitive to changes in your script, since you'd need to make sure that $flag can never be anything but true or false. It would be better to use a string comparison here, like in the test below.

flag=false
while [ "$flag" != "true" ]
do
   read x
   if [ "$x" = "true" ]
   then
     flag=true
   fi
   echo "${x} : ${flag}"
done

There's probably a better way to express the logic you're after. For example, you could make an infinite loop and break it when you detect the termination condition.

while true; do
  read -r x
  if [ "$x" = "true" ]; then break; fi
  echo "$x: false"
done
share|improve this answer

This works for me:

flag=false
while [[ "$flag" == "false" ]]
do
   read x
   if [[ "$x" == "true" ]]
   then
     flag=true
   fi
   echo "${x} : ${flag}"
done

But, actually, what you should do is replace your while with:

while ! $flag
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.