vjwilson
vjwilson

Reputation: 833

Accept multiple lines of input in a bash script

I am in the middle of writing a bash script. The pending point I am stuck with is how to accept multiple inputs from the user at a time.

To be specific, a user must be able to input multiple domain names when the script asks to enter the input.

Example, script running portion:

Enter the domain names :

and user must be able to enter the domain names line by line either by entering each of them manually or he/she just have to copy domain names list from somewhere and able to paste it in the script input, like as follows:

domain1.com
domain2.com
domain3.com
domain4.com

Is it possible?.

Upvotes: 8

Views: 11979

Answers (4)

S Hadd
S Hadd

Reputation: 11

Here's what I would up doing in a situation where I had to have a BASH script ask for a pem format certificate:

echo "Paste your multi-line text into the terminal, ending with two blank lines"
while [ 1 ]; do
  read line
  echo $line >> file.txt
  lastline=$line
  if [ "${lastline}${line}" == "" ]; then break; fi
done

Upvotes: 1

Theodore R. Smith
Theodore R. Smith

Reputation: 23259

So @John1024's answer really set me down the right path, but it was still super confusing to me on how to get this data not only assigned to a variable, but also importantly, to preserve both whitespace and newlines.

After many StackOverflow and StackExchange answers later, I have created with the following snippet that shows how. It is from my Uber BashScripts project @ wifi-autorun-on-connect.installer:

#############################################################
# Grab the script from an existing file -or- user input...  #
#                                                           #
# Copyright © 2020 Theodore R. Smith                        #
# License: Creative Commons Attribution v4.0 International  #
# From: https://github.com/hopeseekr/BashScripts/           #
# @see https://stackoverflow.com/a/64486155/430062          #
#############################################################
function grabScript()
{
    if [ ! -z "$1" ] &&  [ -f "$1" ]; then
        echo $(<"$1")
    else
        echo "" >&2
        echo "Please type/paste in bash script you wish to be run when NetworkManager connects to '${HOTSPOT}'." >&2
        echo "Press CTRL+D when finished." >&2
        echo "You should start with '#!/bin/bash'..." >&2
        echo "" >&2

        # Read user input until CTRL+D.
        # @see https://stackoverflow.com/a/38811806/430062
        readarray -t user_input

        # Output as a newline-dilemeted string.
        # @see https://stackoverflow.com/a/15692004/430062
        printf '%s\n' "${user_input[@]}"
    fi
}

SCRIPT=$(grabScript "$2")

# Preserve white spaces and newlines.
# @see https://stackoverflow.com/a/18018422/430062
echo "$SCRIPT"

Upvotes: 2

John1024
John1024

Reputation: 113994

Yes, you can: use readarray:

printf "Enter the domain names: "
readarray -t arr
# Do something...
declare -p arr

The last line above just documents what bash now sees as the array.

The user can type or copy-and-paste the array names. When the user is done, he types Ctrl-D at the beginning of a line.

Example:

$ bash script
Enter the domain names: domain1.com
domain2.com
domain3.com
domain4.com
declare -a arr='([0]="domain1.com" [1]="domain2.com" [2]="domain3.com" [3]="domain4.com")'

Upvotes: 8

sat
sat

Reputation: 14979

Use loop:

#!/bin/bash

arrDomains=()
echo "Enter the domain names :"

while read domain
do
    arrDomains+=($domain)
    # do processing with each domain
done

echo "Domain List : ${arrDomains[@]}"

Once you have entered all domain names press ctrl + D to end of input.

Upvotes: 8

Related Questions