Creating Interactive Shell Scripts

Creating Interactive Shell Scripts

I should probably preface this post by saying that I have a few Achilles' heels when it comes to programming: naming things, writing regex, and remembering how to do anything when it comes to shell scripts.

Don't get me wrong, I feel like I'm pretty decent when it comes to working around the command line, but for some reason I can never recall how to do basic things in shell scripts that would almost be instantaneous in other languages.

Now that I've properly lowered the bar, we can get to the meat of this post: creating interactive shell scripts. I don't think all scripts need to have interactive menus, but then can definitely make it easier to do certain tasks and create a more guided experience.

Basic Select

At the core the interactive scripts in this example is the select statement. It allows you to present your users with a list of options that they can choose from. Each option is given a numeric representation and can be chosen by typing that number into the prompt. Here is a basic example:

#!/bin/bash

options=(
    "apple"
    "milkshake"
    "salad"
)

select option in "${options[@]}"
do
    echo $option
done

When you run this script, the terminal will look like this:

1) apple
2) milkshake
3) salad
#? 

The #? is the prompt and you can enter any of those option in the list, if you choose 1, we end up printing out the selected option like this:

1) apple
2) milkshake
3) salad
#? 1
apple
#? 

Shnazzing Things Up

Instead of the #? prompt, you can have a custom prompt by setting a reserved variable named PS3. We could do that like so:

#!/bin/bash

options=(
    "apple"
    "milkshake"
    "salad"
)

PS3="What would you like for dinner? "
select option in "${options[@]}"
do
    echo $option
done

When we run this, our terminal looks like this:

1) apple
2) milkshake
3) salad
What would you like for dinner? 

Breaking Out of the Select

You may have noticed by now, but if you select an option and hit enter, you'll be prompted again for another selection like this:

1) apple
2) milkshake
3) salad
What would you like for dinner? 1
apple
What would you like for dinner? 2
milkshake
What would you like for dinner? 3
salad
What would you like for dinner? 

There may be use cases where you may want to take in multiple, but at some point, you'll want to break out and do something else in the script or exit. All we have to do is add a break to our script to do that:

#!/bin/bash

options=(
    "apple"
    "milkshake"
    "salad"
)

PS3="What would you like for dinner? "
selected_option=""
select option in "${options[@]}"
do
    selected_option=$option
    break
done

echo "Enjoy your $selected_option!"

When we run the script, it would look like the following:

1) apple
2) milkshake
3) salad
What would you like for dinner? 1
Enjoy your apple!

There are a lot of possibilities using select statements in this way and can make the developer experience that much better.