7

I have a problem with boolean for while loop. As such, I switch to for loop instead. But still, I cannot change the value of a boolean after the condition is met.

doFirst= true
    for (( j=1; j<=7; j++))
    do
            letter="A"
            seatChoses=$letter$j

            flagRand=$(echo $flightSeatBooked | awk -v flseatRand=$flightSeatBooked -v orseatRand=$seatChoses '{print match(flseatRand, orseatRand)}')
            if  $doFirst ; then
            **$doFirst= false** // Here is the error!
                if [ $flagRand -eq 0 ]; then
                    echo "System generated a slot, "$seatChoses" for you. [Y or N]"
                fi
            fi

    done
4
  • 1
    Tried removing the $? doFirst = false Commented Nov 25, 2012 at 6:26
  • In your echo, you don't need the quotes around $seatChoses. Commented Nov 25, 2012 at 6:27
  • Hi Anders, I am actually accessing the same variable as declared in the first line... Can I still remove the $? Commented Nov 25, 2012 at 6:43
  • The line marked 'here is the error' should read (no spaces) doFirst=false. No $. It's still an aconventional way of doing business, but it will at least work. Commented Nov 25, 2012 at 7:02

2 Answers 2

21

There is no such thing as a boolean value in a shell script (that is, something you can store in a variable, and treat as a boolean). true and false are commands; true exits with value 0, and false exits with a nonzero value. An if statement in bash taks a command; if that command returns 0, then the then clause is executed, otherwise the else clause is.

doFirst= true

This line doesn't do what you expect at all. In a shell script, you cannot have any spaces after the equals sign. The space means you're done with the assignment, and now writing a command. This is equivalent to:

doFirst="" true

Furthermore, if you have an assignment before a command (like this), that doesn't actually perform the assignment in the shell. That sets that environment variable in the environment for that command alone; the assignment has no effect on anything outside of that command.

if  $doFirst ; then

This expands the $doFirst variable, and tries to interpret the result as a command. Oddly, if $doFirst is undefined (which it is, as I explain above), this takes the then branch. At that point, you make your first mistake again, trying to set a variable to be false, and again, nothing happens; $doFirst is left undefined. You make the further mistake of trying to assign $doFirst; you use $ to get the value of a variable, when setting, you use the bare name.

My recommendation would be to not try to use booleans in Bash; just use strings instead, and check the value of the string. Note that I remove the space, so now I'm setting it to that exact string; and there is no command, so this sets the variable within the shell, not in the environment for a single command:

doFirst=true
# ...
   if [ $doFirst = true ]; then
       doFirst=false
   # ...
Sign up to request clarification or add additional context in comments.

5 Comments

Hi @Brian, Thanks the for coaching. However, it came out this error for your 3rd line. How do I explain? [: true: integer expression expected
@BryanWong Sorry, use == instead of -eq; -eq is for numbers, == is for strings. Edited my answer.
@BrianCampbell: Bash does, in fact, have booleans. I was skeptical at first, but I did some sleuthing. You can try it yourself. The if-statement behaves as a boolean, not as a string that's either set or unset.
@siride The if statement acts on a boolean, but on the return value of the command you pass, not on the string value of a variable. So, Bash has boolean return values (though with the somewhat counterintuitive mapping of 0 to true and any nonzero value to false), but you can't store the return value in a variable and then test it directly with if; you would need to use if [ $var -eq 0 ], which is running the [ (or test) command, and checking the return value of that command. Essentially, Bash has boolean exit codes, but no boolean variables.
@siride It can be somewhat confusing, because it does have true and false, and operators like && and ||. true and false are commands, which return 0 and non-zero; and && and || operate based on the exit codes of commands. So you can write if true && false; then ..., and it works. But you can't store that. foo=$(true) stores the standard out of true in foo, not the return value. true; foo=$? stores the return value; but you can't then say if $foo; then ....
2

Are you actually putting a space between the = and the "true"/"false" or is that a formatting error? That's one of your problems.

Another, as mentioned by Anders Lindahl in the comment section, is that when you set a variable in shell scripting, you cannot use the $ in the front. You must say

doFirst=false

Again, note that there are no spaces around the equals sign.

2 Comments

Hi siride, I am actually accessing the same variable as declared in the first line... Can I still remove the $?
You use $ when reading variables, not when assigning the variable. E.g. doFirst=false versus if $doFirst.

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.