LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
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 01-19-2012, 01:53 PM   #1
Ineed$
LQ Newbie
 
Registered: Jan 2012
Posts: 4

Rep: Reputation: Disabled
Trouble reading input inside bash while loop


Hi all , its been a while since I wrote a bash script but I've run into some trouble in the while clause. The answer reads in fine but it doesn't register that a valid answer has been entered and just assumes that every answer entered is invalid.

I think it has to do with how Im doing on the comparisons , if anyone could provide any insight as to why this is not working I would appreciate it.


Code:
#!/bin/bash

# script to list all the files in the downloads directory and ask the user
# if they wish to move the files and if so , into which directory
# Eg Music Videos Pictures Distros etc



EX_HDD="/media/Expansion\ Drive/"



for f in $(ls "$HOME/Downloads/")

do



        echo "Would you like to move $f to External HDD? Y/N"
        read answer


        while  [ '$answer'  !=  'Y' ]  ||  [  '$answer' !=  'N' ]   # Problem line
        do
                echo "Answer must be of the form Y or N"
                echo "Would you like to move $f to External HDD? Y/N"
                echo "Answer is $answer"
                read answer

        done

        echo "working so far"

done
Sample output:

Would you like to move 119305-GlassMaxX.tar.gz to External HDD? Y/N
Y
Answer must be of the form Y or N
Would you like to move 119305-GlassMaxX.tar.gz to External HDD? Y/N
Answer is Y
N
Answer must be of the form Y or N
Would you like to move 119305-GlassMaxX.tar.gz to External HDD? Y/N
Answer is N
Y
Answer must be of the form Y or N
Would you like to move 119305-GlassMaxX.tar.gz to External HDD? Y/N
Answer is Y
HJHJ
Answer must be of the form Y or N
Would you like to move 119305-GlassMaxX.tar.gz to External HDD? Y/N
Answer is HJHJ
 
Old 01-19-2012, 02:07 PM   #2
Ser Olmy
Senior Member
 
Registered: Jan 2012
Distribution: Slackware
Posts: 3,333

Rep: Reputation: Disabled
Well, you are looping on the condition that $answer is either unlike Y or unlike N. Since it can't be both Y and N at the same time, the while loop continues indefinitely.

Also, the single quotes prevent shell expansion of the variable, so you're comparing the literal string $answer rather than the contents of the variable.

How about: while [ "$answer" != "Y" ] && [ "$answer" != "N" ]
 
Old 01-19-2012, 02:13 PM   #3
Ineed$
LQ Newbie
 
Registered: Jan 2012
Posts: 4

Original Poster
Rep: Reputation: Disabled
Thanks Ser Olmy, that did the trick, it works fine now. I appreciate it.
 
Old 01-20-2012, 09:05 AM   #4
Reuti
Senior Member
 
Registered: Dec 2004
Location: Marburg, Germany
Distribution: openSUSE 15.2
Posts: 1,339

Rep: Reputation: 260Reputation: 260Reputation: 260
Maybe it can also be phrased as a regex and avoid an external program to be called:
Code:
while ! [[ "$answer" =~ ^[NY]$ ]]; do
 
Old 01-20-2012, 09:20 AM   #5
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 9,999

Rep: Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190Reputation: 3190
Or if looking for the negative maybe use an 'until' loop.
 
Old 01-21-2012, 06:27 AM   #6
David the H.
Bash Guru
 
Registered: Jun 2004
Location: Osaka, Japan
Distribution: Arch + Xfce
Posts: 6,852

Rep: Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037Reputation: 2037
Checking user input is more traditionally done with a case statement, and embedding it in a continuous loop will make it repeat until you get the correct answer and manually break out of it.

Code:
while true; do 
	echo "Would you like to move $f to External HDD? Y/N"
        read answer

	case $answer in

		y|Y*) echo "You answered yes." ; break  ;;

		n|N*) echo "You answered no." ; break  ;;

		*) echo "Answer must be yes or no.  Try again."  ;;

	esac
done
Also consider using a select loop, which is a built-in that provides a pre-formatted variation of the above for simple menus.

Second, parsing ls for filenames is not a good idea, particularly in a for loop. Just use shell globbing.

Code:
for f in "$HOME/Downloads/"* ; do
     ....
done
For more advanced lists, you should switch to using find and a while+read loop.
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

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
[SOLVED] Bash - While Loop reading from two lists simultaneously - nested while loop wolverene13 Programming 11 10-01-2011 05:00 PM
BASH: Reading long filenames into an array using a loop DaneM Programming 12 09-11-2009 07:24 AM
bash: variables inside while loop J_Szucs Programming 5 07-19-2009 08:24 AM
trouble with expr inside a while loop farkus888 Linux - General 5 04-06-2007 03:19 AM
Bash: command works but not inside of for loop. RijilV Programming 3 05-21-2006 08:29 PM

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

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

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