Automating Inputs for Interactive Shells

Automating Inputs for Interactive Shells

Leave no task unautomated

Overview

As a developer, your interaction with a shell is inevitable. They can be useful for navigating directories, running commands, and more.

There’s a large variety of shell commands, some of which can even be interactive. You enter a shell command, and it asks you a question.

Some of these are set up so you can enter anything you want, while others make you select from a list of options.

Either way, the command doesn’t proceed till you provide your input.

Imagine if this can be automated? You’ll no longer have to wait for the command. Once you run it, you can go about your day, grab a cup of coffee, and relax till the task is over.

News flash- it can be done, and in this post, we’ll show you how.

How it works

The idea is simple. When you run an interactive command, it looks for some inputs.

What if you could pass the inputs beforehand? That way, instead of waiting, it knows what you want to enter.

Example Script

Let’s create an example script so we know what we’re working with. Let’s call it interactive.sh.

#!/usr/bin/env bash

echo "Good day! Today, I'll be asking some questions so I can know you better."

echo "What is your name?"
read -r name

echo "What is your hobby?"
read -r hobby

echo "Are you a Developer?"

echo -n "y/n: "
read -r dev

echo
echo "Answers:"
echo "1. $name"
echo "2. $hobby"
echo "3. $dev"

When run with ./interactive.sh, it looks like this:

Interactive Shell Example.png

The shell prints a question and waits for us to enter something.

Once that’s done, it proceeds to the next question. It waits for our input before proceeding.

Some scripts even provide you with a list of options to choose from.

Now let’s see how you can automate this.

Automating Inputs

The core idea is for you to pass in the values to the script way before it asks for values. That way, instead of user input, the script takes the values you’ve passed, inserting them at each instance of user input.

As with any problem in programming, there are multiple solutions.

Input File

This is one of our favorite ways of automating inputs.

We create a file that holds all the inputs we need.

What’s so great about this? We can set the inputs in a file, which can be run with a single, short command.

We’ll start by creating an input file. We’ve named it inputs, but you can name it whatever you want.

NeoMax97
Gaming
y

This file contains all of our inputs. Each line represents a particular input. Since we have three questions, we have three lines.

To pass this in, we simply run ./interactive.sh < inputs.

Interactive Shell - Input File.png

As you can see, it passes the inputs and the command completes itself.

You may notice that you cannot see the actual inputs as they are being entered. You can see that it’s entered correctly because you print the answers at the end.

Not all scripts will do this. However, by printing the inputs at the end, we know that they were passed correctly. Simple, right?

Piping Inputs

Pipes are generally used in shells to pass values. You can use the same feature here, to pass in your inputs.

Interactive Shell - Piping Inputs.png

Here, you echo your inputs first, then pipe (|) them into our script.

It doesn’t look as clean as using an input file, but you can avoid creating a file altogether.

In some cases, creating a file could be problematic, get in the way, cause confusion or not follow the practices set by a team.

In any case, this is another way to pass inputs. It’s always better to have multiple options.

Here Document

A ‘Here Document’ is like an inline document you pass to the shell. It looks for a word that works as your start and end indicator. Any content between these indicators will be considered as content for the file.

Interactive Shell - Here Document.png

As you can see here, you feed your Here Document to the script using <<.

Inputs is your start and end word (has to be the same string).

NeoMax97, Gaming and y are your inputs (content of the Here Document). This is similar to the Input File approach, only you’re creating the document inline instead of an actual file.

This file doesn’t get saved anywhere. It’s created for that particular run. That’s it. After that, it’s gone, as it’s served its purpose.

Note that the shell here looks different compared to the earlier screenshots. We used Fish as our primary shell.

However, Here Documents and Here Strings are not supported in Fish (by design). We had to run bash in Fish to enter a bash shell in which we’re running these commands. Here Documents and Here Strings may not be supported in custom shells, so do keep that in mind.

Here String

Similar to a Here Document, a Here String is an inline string that you can pass to your script.

Interactive Shell - Hero String - Single Quotes.png

As you can see here, you pass your Here String using <<<.

Your string starts with a $, followed by your string in single quotes ('). Each line needs to be escaped using a newline character (\n). It doesn’t look as pretty, but if you just want to test something quickly, this method works just fine.

Note that the single quotes are important, as it evaluates any and all escape characters in the string. If you use double quotes ("), it will accept the entire string as one input.

Interactive Shell - Hero String - Double Quotes.png

As mentioned earlier, Here Strings aren’t supported by Fish either, so it’s possible that other custom shells don’t support this feature.

Here Strings work fine on regular bash, though.

Conclusion

The beauty of programming? Problems often have multiple solutions. Solutions can be optimized, and some can even be automated.

Oftentimes a shell command is being run in an environment where you cannot manually enter inputs.

You can pass your inputs to the command directly when running the command, and in multiple ways, too.

By automating inputs, the scripts not only run faster, but save you the headache of being present near the machine just to enter a few characters. The time you save can be used for other tasks or for a relaxing break.