LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 02-02-2009, 08:05 AM   #1
skuzye
Member
 
Registered: Jul 2008
Location: São Paulo - Brazil
Distribution: Fedora 17
Posts: 97

Rep: Reputation: 15
Unhappy 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?
 
Old 02-02-2009, 08:22 AM   #2
pixellany
LQ Veteran
 
Registered: Nov 2005
Location: Annapolis, MD
Distribution: Mint
Posts: 17,809

Rep: Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743Reputation: 743
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.
 
Old 02-02-2009, 10:19 AM   #3
skuzye
Member
 
Registered: Jul 2008
Location: São Paulo - Brazil
Distribution: Fedora 17
Posts: 97

Original Poster
Rep: Reputation: 15
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.

Last edited by skuzye; 02-02-2009 at 10:20 AM. Reason: spell error correction
 
Old 02-02-2009, 01:07 PM   #4
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,786

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
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".
 
Old 02-04-2009, 07:10 AM   #5
skuzye
Member
 
Registered: Jul 2008
Location: São Paulo - Brazil
Distribution: Fedora 17
Posts: 97

Original Poster
Rep: Reputation: 15
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
 
Old 02-04-2009, 07:19 AM   #6
jschiwal
LQ Guru
 
Registered: Aug 2001
Location: Fargo, ND
Distribution: SuSE AMD64
Posts: 15,733

Rep: Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682Reputation: 682
Use -o inside [[...]] instead of ||. Use || to separate two commands, where the second command is executed when the first one is successful.
 
Old 02-04-2009, 07:23 AM   #7
skuzye
Member
 
Registered: Jul 2008
Location: São Paulo - Brazil
Distribution: Fedora 17
Posts: 97

Original Poster
Rep: Reputation: 15
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

Last edited by skuzye; 02-04-2009 at 07:27 AM.
 
Old 02-04-2009, 10:59 AM   #8
ntubski
Senior Member
 
Registered: Nov 2005
Distribution: Debian, Arch
Posts: 3,786

Rep: Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083Reputation: 2083
Quote:
Originally Posted by skuzye View Post
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.
 
Old 02-04-2009, 11:31 AM   #9
gnashley
Amigo developer
 
Registered: Dec 2003
Location: Germany
Distribution: Slackware
Posts: 4,928

Rep: Reputation: 612Reputation: 612Reputation: 612Reputation: 612Reputation: 612Reputation: 612
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" ]]
 
Old 02-04-2009, 01:31 PM   #10
skuzye
Member
 
Registered: Jul 2008
Location: São Paulo - Brazil
Distribution: Fedora 17
Posts: 97

Original Poster
Rep: Reputation: 15
Quote:
Originally Posted by ntubski View Post
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.
 
  


Reply

Tags
bash, loop, script, while



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
how to loop over text file lines within bash script for loop? johnpaulodonnell Linux - Newbie 9 07-28-2015 03:49 PM
Unary Operator expected. Bash script Blackout_08 Programming 2 06-22-2006 02:21 PM
Infinite Loop ewt3y Programming 3 08-16-2005 09:48 AM
bash script and the , operator xviddivxoggmp3 Programming 1 08-14-2004 12:33 AM
facing problem in increment operator of set :infinite LOOP ashwinipahuja Programming 0 06-03-2004 12:05 AM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 03:16 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration