10

I am trying to create a while loop in bash that won't continue until the user enters the word "next". I can't seem to figure out how to use strings for the condition though.

#Beginning of code
echo -e "Please type next to continue."
read word 
while [ "$word" -ne "next" ]
do 
    read word
done
#the rest of the code
1
  • 1
    when you compare strings you should use = or ==. So your while loop should look like: while [ "$word" = "next" ] The -eq is used for numeric comparision Feb 13, 2015 at 6:13

4 Answers 4

17

Use != instead of -ne

echo -e "Please type next to continue."
read word 
while [ "$word" != "next" ]
do 
    read word
done

Check this for comparison operators. http://tldp.org/HOWTO/Bash-Prog-Intro-HOWTO-11.html

4

As others have stated you should not use the -ne integer comparison to compare strings - rather you should use =/!= in test [ brackets ]. Still though, even that is brittle at best - the strings must match exactly, and '' does equal ''. It is often better to handle cases in that context:

set --
while   read  word
        case $?$#$word            in 
        ($?$#[Nn][Ee][Xx][Tt]) ! :;;
        ([!0]*|05*) ! break       ;;esac
do      set '' "$@"
done   

Provided a default value for $IFS (which is worth looking into if you plan to do shell reads), that should work for any upper/lower value of next (if you require it) and keep the loop from running away without end.

1
  • 1
    Hmmm... Now I'm wondering why I thought it should have been easier the other way. But I think it was because I considered that an EOF should not return true in the same way 5 consecutive failures should not return true.
    – mikeserv
    Feb 13, 2015 at 9:58
4

I think you want:

echo 'Please type "next" to continue.'
while read word && [ "$word" != next ]; do
  : something in the loop if needed
done

It's a good idea to also check for end-of-file on stdin (here by checking the exit status of read).

1
  • I had read ... && case at first, but it seemed easier just to set a low limit because a runaway tty read loop would be more annoying than 5 reads. Still - it was lazy. I suppose I could do $?.$#$word now that I think about it...
    – mikeserv
    Feb 13, 2015 at 9:44
2

You are using the wrong comparison operator. You should use "!=" for string and "-ne" for integers as follows:

#Beginning of code
echo -e "Please type next to continue."
read word
while [ "$word" != "next" ]
do
    read word
done
#the rest of the code

Checkout this page: Advanced bash Scripting: Comparison Operations

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .