2

I want to write a script in bash which is checking the user input if it is equal to "stringA" or "stringB" and in case it is equal to one of these strings it should print the user input. My code is:

#!/bin/bash

echo "Please enter your choice (stringA or stringB): "
read result

while [[ (${result,,} != 'stringa') || (${result,,} != 'stringb') ]]; do
        echo Please enter only stringA or stringB:
        read result
done

echo "You have selected $result!"

exit

Unfortunately this code doesn't work and loop infinitely. I can only compare if the $result is equal to one of the strings removing the || and the second part of the while loop. I have tried to replace the || with -o but I got the following error:

./chk.sh: line 12: syntax error in conditional expression
./chk.sh: line 12: syntax error near `-o'
./chk.sh: line 12: `while [[ (${result,,} != 'stringa') -o (${result,,} != 'stringb') ]]; do' 
3

That's because you want to use &&, not ||.

You want to repeat the loop if the result isn't stringA AND it isn't stringB. No string can be equal to both of them, which whould end your loop.

You can also use a pattern in [[ ... ]]:

while [[ ${result,,} != string[ab] ]]
2

The issue in your code is that your loop loops while $result is not the same as both stringA and stringB (at the same time). You may want to use

while [[ "${result,,}" != 'stringa' ]] && [[ "${result,,}" != 'stringb') ]]

or

until [[ "${result,,}" == 'stringa' ]] || [[ "${result,,}" == 'stringb') ]]

To get a user to pick one of a few choices, don't get them to type in long strings. Instead, provide them with a simple menu to pick from.

Suggestion:

#!/bin/bash

PS3='Your choice: '
select result in 'stringA' 'stringB'; do
    case $REPLY in
        [12])
            break
            ;;
        *)
            echo 'Invalid choice' >&2
    esac
done

printf 'You picked %s!\n' "$result"

Running this:

$ bash script.sh
1) stringA
2) stringB
Your choice: 3
Invalid choice
Your choice: 2
You picked stringB!
  • True, though here it looks like the OP wants to explicitly allow users to enter STRINGA, sTringA..., so allows for users to choose between 256 different valid values. – Stéphane Chazelas Jun 4 '18 at 15:37
  • @StéphaneChazelas Indeed. – Kusalananda Jun 4 '18 at 15:41
1
#!/bin/bash

echo "Please enter your choice (stringA or stringB): "
read result

while ! [ "${result,,}" = 'stringa' -o "${result,,}" = 'stringb' ]; do
        echo Please enter only stringA or stringB:
        read result
done

echo "You have selected $result!"

exit

In textspeech while not result is stringa or result is stringb do...

be aware of " around your variables, else you will get an error if the var $result is empty.

  • 1
    They were using the [[ ... ]] construct, it doesn't have the same problem with unquoted variables as normal commands do. On the other hand, using -o with test/[, is a bit problematic since it can get confused about it if the other strings look like operators. Here, if $result contains a ! (a lone exclamation point), [ drops an error. Instead, you can put the condition on the shell level and write [ some test ] || [ another test ] (or use [[ .. ]] and || within it) – ilkkachu Nov 23 '17 at 17:18
  • @FaxMax, it works very well, thank you very much! – Georgе Stoyanov Nov 24 '17 at 9:51
0

A sh variant, and would remove the problems associated with ${var,,} which uses the locale to convert strings (lowercase I is not i for everyone for instance):

#! /bin/sh -
while true; do
  printf %s "Please enter your choice (stringA or stringB): "
  IFS= read -r result || exit # exit on EOF
  case $result in
    ([sS][tT][rR][iI][nN][gG][aAbB]) break
  esac
  echo >&2 Invalid choice.
done
  • This is good, unless stringA and stringB are just placeholders for longer strings, or strings that may be totally different from each other. – Kusalananda Jun 4 '18 at 15:36

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.