Interactive versus non-interactive scripts

The script we have created so far uses user input, but it can't really be called interactive. As soon as the script is fired off, with or without arguments to the parameters, the script runs and completes.

But what if we do not want to use a long list of arguments, instead prompting the user for the information that is needed?

Enter the read command. The basic usage of read looks at input from the command line, and stores it in the REPLY variable. Try it out yourself:

reader@ubuntu:~$ read
This is a random sentence!
reader@ubuntu:~$ echo $REPLY
This is a random sentence!
reader@ubuntu:~$

After you start the read command, your terminal will go down a line and allow you to type anything you want. As soon as you hit Enter (or, actually, until Bash encounters the newline key), the input will be saved into the REPLY variable. You can then echo this variable to verify it has actually stored your text.

read has a few interesting flags which make it more usable in shell scripting. We can use the -p flag with an argument (the text to display, surrounded by quotes) to present the user with a prompt, and we can supply the name of the variable in which we want to store the response as the last argument:

reader@ubuntu:~$ read -p "What day is it? "
What day is it? Sunday
reader@ubuntu:~$ echo ${REPLY}
Sunday
reader@ubuntu:~$ read -p "What day is it? " day_of_week
What day is it? Sunday
reader@ubuntu:~$ echo ${day_of_week}
Sunday

In the previous example, we first used read -p without specifying a variable where we want to save our response. In this case, read's default behavior places it in the REPLY variable. A line later, we ended the read command with the text day_of_week. In this case, the full response is saved into a variable with this name, as can be seen in the echo ${day_of_week} right after.

Let's use read in an actual script now. We'll first create the script using read, and then using positional arguments as we have up to now:

reader@ubuntu:~/scripts/chapter_08$ vim interactive.sh
reader@ubuntu:~/scripts/chapter_08$ cat interactive.sh
#!/bin/bash

#####################################
# Author: Sebastiaan Tammer
# Version: v1.0.0
# Date: 2018-09-09
# Description: Show of the capabilities of an interactive script.
# Usage: ./interactive.sh
#####################################

# Prompt the user for information.
read -p "Name a fictional character: " character_name
read -p "Name an actual location: " location
read -p "What's your favorite food? " food

# Compose the story.
echo "Recently, ${character_name} was seen in ${location} eating ${food}!

reader@ubuntu:~/scripts/chapter_08$ bash interactive.sh
Name a fictional character: Donald Duck
Name an actual location: London
What's your favorite food? pizza
Recently, Donald Duck was seen in London eating pizza!

That worked out pretty well. The user could just call the script without looking at how to use it, and is further prompted for information. Now, let's copy and edit this script and use positional arguments to supply the information:

reader@ubuntu:~/scripts/chapter_08$ cp interactive.sh interactive-arguments.sh
reader@ubuntu:~/scripts/chapter_08$ vim interactive-arguments.sh
reader@ubuntu:~/scripts/chapter_08$ cat interactive-arguments.sh
#!/bin/bash

#####################################
# Author: Sebastiaan Tammer
# Version: v1.0.0
# Date: 2018-09-09
# Description: Show of the capabilities of an interactive script,
# using positional arguments.
# Usage: ./interactive-arguments.sh <fictional character name>
# <actual location name> <your favorite food>
#####################################

# Initialize the variables from passed arguments.
character_name=${1}
location=${2}
food=${3}

# Compose the story.
echo "Recently, ${character_name} was seen in ${location} eating ${food}!"

reader@ubuntu:~/scripts/chapter_08$ bash interactive-arguments.sh "Mickey Mouse" "Paris" "a hamburger"
Recently, Mickey Mouse was seen in Paris eating a hamburger!

First, we copied the interactive.sh script to interactive-arguments.sh. We edited this script to no longer use read, but instead to grab the values from the arguments passed to the script. We edited the header with the new name and the new usage, and we ran it by supplying another set of arguments. Once again, we were presented with a nice little story.

So, you might be wondering, when should you use which method? Both methods ended with the same result. However, as far as we're concerned, both scripts aren't equally readable or simple to use. Look at the following table for pros and cons for each method:

Pros

Cons

Read
  • User does not need to be aware of arguments to supply; they can just run the script and be prompted for any information needed
  • It is not possibly to forget to supply information
  • If you want to repeat the script multiple times, you need to type the responses every time
  • Cannot be run non-interactively; for example, in a scheduled job
Arguments
  • Can be repeated easily
  • Can be run non-interactively as well
  • User needs to be aware of arguments to supply before attempting to run the script
  • It is much easier to forget to supply part of the information needed

 

Basically, the pros for one method are the cons for the other, and vice-versa. It seems as though we can't win by using either method. So, how would we create a robust interactive script that we can also run non-interactively?

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.118.128.105