user5674825
user5674825

Reputation:

Shell Bash: How to prompt a user to select from a dynamically populated list?

newbie here!

On a Shell Script (bash), after prompting user for name/password the script should read from a server.list and generate option for selection.

How do I provide the user the options from server.list like so:

#Please select from the server list:  

1) 10.1.1.xx

2) 10.1.1.xx

3) 10.1.1.xx

Select option [1]:  

Any help would be appreciated!

Upvotes: 5

Views: 12398

Answers (3)

trolologuy
trolologuy

Reputation: 2025

Or based on @nwk's answer, but using a for loop and getting the output from another command (where get_server_ips is a command that returns a list of IPs):

echo 'Please select from the IP list:'
ips=$(get_server_ips)
echo -e "$ips" | nl;
count="$(echo -e "$ips" | wc -l)"
read -p 'Select option: ' n
for i in `echo -e "$ips" | nl`;
do
    if [ "$n" == "$i" ]; then
        value=$(echo -e "$ips" | sed -n ${i}p) 2>&1
        break
    fi
done;
echo "The user selected option number $n: '$value'"

Upvotes: 0

Juan Diego Godoy Robles
Juan Diego Godoy Robles

Reputation: 14955

Supposing this source file:

$ cat server.list 
10.1.1.xx
10.1.2.xx
10.1.3.xx

Short answer:

select ip in $(cat server.list); do 
   echo $REPLY $ip
done

Demo

$ select ip in $(cat server.list); do echo $REPLY $ip; done
1) 10.1.1.xx
2) 10.1.2.xx
3) 10.1.3.xx
#? 1
1 10.1.1.xx
#? 2
2 10.1.2.xx

You will have to implement a case loop to do something useful with the ip variable.

Example

select ip in $(cat server.list) exit; do 
   case $ip in
      exit) echo "exiting"
            break ;;
         *) echo ip $ip;
   esac
done

Upvotes: 7

nwk
nwk

Reputation: 4050

Since an answer already covers how to accomplish this using Bash's select here are two other options.

1. Plain POSIX shell

The following is how you can implement presenting the user with a choice of one option from a list of options in a POSIX shell script without relying on Bash's extensions.

Code

#!/bin/sh
echo 'Please select from the server list:'
nl server.list
count="$(wc -l server.list | cut -f 1 -d' ')"
n=""
while true; do
    read -p 'Select option: ' n
    # If $n is an integer between one and $count...
    if [ "$n" -eq "$n" ] && [ "$n" -gt 0 ] && [ "$n" -le "$count" ]; then
        break
    fi
done
value="$(sed -n "${n}p" server.list)"
echo "The user selected option number $n: '$value'"

A sample interaction

Please select from the server list:
     1  10.1.1.1
     2  10.1.1.2
     3  10.1.1.3
     4  10.1.1.4
     5  10.1.1.5
Select option: 0
Select option: -1
Select option: w
list.sh: line 9: [: w: integer expression expected
Select option: 3
The user selected option number 3: '10.1.1.3'

2. Using dialog(1)

If you have dialog(1) installed on the user's machine you can present the user with pseudographical menu.

Code

#!/bin/sh
tempfile="$(mktemp)"
while true; do
    dialog --menu 'Please select from the server list' 18 70 15 $(nl server.list) 2>"$tempfile" && break
done
n="$(cat "$tempfile")"
value="$(sed -n "${n}p" server.list)"
rm "$tempfile"
echo "The user selected option number $n: '$value'"

Screenshot

The dialog running in a terminal

Upvotes: 6

Related Questions