LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Trouble reading input inside bash while loop (https://www.linuxquestions.org/questions/programming-9/trouble-reading-input-inside-bash-while-loop-924653/)

Ineed$ 01-19-2012 01:53 PM

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

Ser Olmy 01-19-2012 02:07 PM

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" ]

Ineed$ 01-19-2012 02:13 PM

Thanks Ser Olmy, that did the trick, it works fine now. I appreciate it.

Reuti 01-20-2012 09:05 AM

Maybe it can also be phrased as a regex and avoid an external program to be called:
Code:

while ! [[ "$answer" =~ ^[NY]$ ]]; do

grail 01-20-2012 09:20 AM

Or if looking for the negative maybe use an 'until' loop.

David the H. 01-21-2012 06:27 AM

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.


All times are GMT -5. The time now is 12:35 AM.