The main issue with your script is that you test the literal string
order for whether it's
yes or not. You probably meant
Another issue is that you run this script, which is a
bash script, using
/bin/sh may not understand some of the extensions that
bash makes to the POSIX shell standard, but you may also just be lucky. Change the first line so that
bash is used instead.
A string comparison in a shell script may be done using
if [ "$order" = "yes" ]; then ...; fi
This is "cheaper" and easier to read than calling
You may also use
case ... esac:
case "$order" in
yes) ... ;;
no) ... ;;
Re-executing the script to have another go is fragile and very unconventional. It will, for example, very likely not work if the script is invoked as
bash script.sh. It is better to introduce a loop that you break out of if the user don't want to have another go.
bash also has a
select loop, that you can use like this:
echo 'Please select protein from this menu:'
select protein in "beans" "lentils" "tofu" "cheese"; do
if [ -z "$protein" ]; then
echo 'Invalid choice' >&2
printf 'You picked %s as protein\n' "$protein"
This allows you to have greater control over the user's input.
A general approach for reading interactive input from a user and then asking about quitting or not:
while true; do
read -p 'Enter data: ' -r data
# use "$data" here for something
read -p 'Again? [Y/n] ' answer
case "$answer" in
[Nn]*) break ;;
Here, you have an outer loop that asks the questions and does some processing. Then it asks the user whether they want to go again. If they answer "No" (anything starting with
break out of the loop.
The test at the end might also be a validation of
$data. If the user entered invalid input in the first
read, you may want to ask again until valid input is given.
The benefit of this is that the
$data (or whatever you read) is alive and available after the input loop, so instead of doing processing on
$data inside the loop, you can do so later.
if-valid exit input-loop