LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (http://www.linuxquestions.org/questions/programming-9/)
-   -   Bash script - Infinite loop caused by a logical OR operator (http://www.linuxquestions.org/questions/programming-9/bash-script-infinite-loop-caused-by-a-logical-or-operator-701629/)

skuzye 02-02-2009 08:05 AM

Bash script - Infinite loop caused by a logical OR operator
 
Hello everyone. After a few hours trying to debug and searching LQ.org and Google and nothing I decided to post so someone could point me somewhere.

Let's get to the point, here's the code:

Code:

freespacecd() {
        #it will help to know that "vazio" means empty  and multisessao means wheter the disk is appendable ornot.

        while [[ "$MULTISESSAO" != "yes" || "$VAZIO" = "no" ]]; do
                VAZIO=$(cdrdao disk-info --device /dev/cdrom | grep "CD-R empty" | cut -c24-27)
                if [ "$VAZIO" != "yes" ]; then
                        MULTISESSAO=$(cdrdao disk-info --device /dev/cdrom | grep "Appendable" | cut -c24-27)
                        if [ "$MULTISESSAO" != "yes" ]; then
                                echo "A mídia não está vazia e não é multisessão. Troquea-a para que o backup prossiga. Aguardando 15 segundos..." #just tell something to the person.
                                eject
                                sleep 15
                                checkcd #check if there's a cd in the drive
                        fi
                fi
        done

The issue is at the while loop which never ends. It seems so right to me. Surely there's something making it not to work.

First time the loop goes $MULTISESSAO is evaluated true and $VAZIO is evaluated true and second time and so it's the opposite: $MULTISESSAO is now true and $VAZIO is false.

I have no ideas anymore. I also tried without with single square brackets "[ ... ]" but it didn't work either.

Any idea?

pixellany 02-02-2009 08:22 AM

You're not testing for TRUE and FALSeE, but rather for the literal strings "yes" and "no".

This aside, the trick is to insert extra echo statements to confirm the values of variables at different points in the program.

skuzye 02-02-2009 10:19 AM

Ok, sorry for the bad question. What I meant was: "is there anything wrong with the condition formation?". Its syntax is right to me and I think for you too since you said nothing about it... Thanks for the answer.

ntubski 02-02-2009 01:07 PM

The conditional syntax looks fine to me (and bash should give an error message if it's not), but I think there is a problem with the cut statement you use:
Code:

| cut -c24-27
This is probably returning three letters, so you get "no " instead of "no".

skuzye 02-04-2009 07:10 AM

Problem solved. I seems that while doesn't support multiple conditions. Here's the resulting code:

Code:

freespacecd() {
        FREECDGO="1"
        while [ "$FREECDGO" -ne "0" ]; do
                VAZIO=$(cdrdao disk-info --device /dev/cdrom | grep "CD-R empty" | cut -c24-27)
                sleep 5
                if [ "$VAZIO" != "yes" ]; then
                        MULTISESSAO=$(cdrdao disk-info --device /dev/cdrom | grep "Appendable" | cut -c24-27)
                        if [ "$MULTISESSAO" != "yes" ]; then
                                echo "A mídia não está vazia e não é multisessão. Troquea-a para que o backup prossiga. Aguardando 15 segundos..."
                                eject
                                sleep 15
                                checkcd
                        fi
                fi
                if [ "$MULTISESSAO" = "yes" ] || [ "$VAZIO" = "yes" ]; then
                        FREECDGO="0"
                fi
        done
}

Thank you for your time. Skuzye

jschiwal 02-04-2009 07:19 AM

Use -o inside [[...]] instead of ||. Use || to separate two commands, where the second command is executed when the first one is successful.

skuzye 02-04-2009 07:23 AM

I'm confused now. Now that you said to use -o I researched and that's quote from the Advanced Bash-Scripting Guide:

Quote:

These are similar to the Bash comparison operators && and ||, used within double brackets.

[[ condition1 && condition2 ]]

The -o and -a operators work with the test command or occur within single test brackets.

if [ "$exp1" -a "$exp2" ]
Quote:

Use || to separate two commands, where the second command is executed when the first one is successful.
I'm sorry but isn't this the "&&" function?

Skuzye

ntubski 02-04-2009 10:59 AM

Quote:

Originally Posted by skuzye (Post 3431785)
I[t] seems that while doesn't support multiple conditions. Here's the resulting code:

Yes it does. Note that in your modified code you only test against "yes", whereas in the original you were also testing against "no". I think this is evidence that my earlier point is correct.

gnashley 02-04-2009 11:31 AM

Yes, && only runs the second statement if the first succeeds and || runs the second statement if the first fai
I usually use them like this:
[ "$exp1" -a "$exp2" ]
[[ "$exp1" ]] && [[ "$exp2" ]]

[ "$exp1" -o "$exp2" ]
[[ "$exp1" ]] || [[ "$exp2" ]]

skuzye 02-04-2009 01:31 PM

Quote:

Originally Posted by ntubski (Post 3432039)
Yes it does. Note that in your modified code you only test against "yes", whereas in the original you were also testing against "no". I think this is evidence that my earlier point is correct.

Sorry I forgot to note that cut is only cutting "no" and not "no ".

I did:

echo "*$VARIABLE*"
and got: *no*.

Thanks gnashley I understood it now.


All times are GMT -5. The time now is 03:34 AM.