Prickle-Prickle
Prickle-Prickle

Reputation: 23

Having trouble with Bash / Shell While Loop String Comparison

I'm learning scripting to help with my work, and I'm just trying to wrap my head around using while loops.

I want to repeat a question if a user doesn't answer with Yes or No. Currently I have that working with an if conditional statement, that was easy, but it simply exits the script if the user doesn't answer with y or n.

I've tried various iterations of the below, figured out that I can't use -ne unless it's an integer, but what I can't seem to get right is the string comparison.

I found much better ways to do this online, but it's pointless to copy-paste those if I'm missing something basic about a simple while loop.

#!/bin/sh

while [ $CONFIRM != "^y"|"^n"] # This is where I'm stuck
do
echo "Please say Yes or No."   # Probably not doing this right either
read CONFIRM                   # Or this
done

if  echo "$CONFIRM" | grep -iq "^n" ; then
echo "Okay, stopping script."
else

#do some cool stuff

fi

Any and all advice appreciated.


And the correct answer is...

#!/bin/bash

shopt -s nocasematch

while ! [[ $CONFIRM =~ ^(y|n) ]]
do
echo "Please say Yes or No."
read CONFIRM
done

echo "Success!"

Upvotes: 2

Views: 1328

Answers (2)

rigglesbee
rigglesbee

Reputation: 108

Try something like this:

while [[ -z $confirm || ( $confirm != y && $confirm != n ) ]]; do
 read confirm
done

Upvotes: 0

chepner
chepner

Reputation: 531718

You are mixing regular expressions with pattern matching.

# Regular expression
while ! [[ $confirm =~ ^(y|n) ]]; do

or

# extended pattern
while [[ $confirm != @(y|n)* ]]; do 

should each do what you want.


The read command takes the name of a variable as its argument.

read confirm

Using a parameter expansion causes read to set the value of the variable whose name is contained in confirm:

$ confirm=foo
$ read $confirm <<< 3
$ echo "$foo"
3

Upvotes: 1

Related Questions