4

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?.

JohnW
  • 345
  • 5
  • 14

3 Answers3

5

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")'
John1024
  • 97,609
  • 11
  • 105
  • 133
  • I published a snippet based in part on this code. I am not sure at all what `declare -p` is supposed to do, but it definitely didn't stick it in a variable. https://gist.github.com/hopeseekr/460700d166487dcd11d2dbd5f36b8077 – Theodore R. Smith Oct 22 '20 at 16:16
  • @TheodoreR.Smith The purpose of `declare -p arr` is to _print_ to stdout the contents of a variable. In the example in the answer, the `declare -p` line is what produces the output `eclare -a arr='([0]="domain1.com" [1]="domain2.com" [2]="domain3.com" [3]="domain4.com")'` – John1024 Nov 07 '20 at 07:42
4

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.

sat
  • 13,503
  • 5
  • 41
  • 62
1

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"
Theodore R. Smith
  • 18,715
  • 12
  • 52
  • 81