2016-03-07 5 views
1

Я пытаюсь сделать сценарий для получения списка ip из файла и показать его на экране с опцией выбора и сделать ssh на этот IP, просто выбрав. Файл выглядит следующим образом;Меню опций с массивом

name1 1.1.1.1 
name2 2.2.2.2 
name3 3.3.3.3 
name4 4.4.4.4 

Ниже сценарий может прочитать список из файла и показывает его на экране, как menu.It показывает как имя и IP-адрес для выбора, но я хочу, чтобы показать меню выбора просто по имени. Как я могу это достичь?

PS3='Please enter your choice: ' 
readarray -t options < ./file.txt 

select opt in "${options[@]}" 
do 
IFS=' ' read name ip <<< $opt 
case $opt in 
     $opt) ssh $ip;; 

esac 
done 

1) name1 1.1.1.1 
2) name2 2.2.2.2 
3) name3 3.3.3.3 
4) name4 4.4.4.4 
Please enter your choice: 1 
+0

Вы отметили свой вопрос [tag: sh], но используете команду 'readarray', которая не существует в оболочке POSIX. Вы уверены, что это не вопрос [tag: bash]? – ghoti

+0

Мое предположение: вы используете версию 'bash' до 4.3, у которой была ошибка, которая требовала, чтобы' $ opt' был указан в этой строке, чтобы расщепление произошло должным образом. Попробуйте 'IFS = '' прочитать имя ip <<<" $ opt "'. – chepner

+0

(Чтобы уточнить, ваш код должен работать нормально в 'bash' 4.3 или новее.) – chepner

ответ

0

Я предполагаю, что это Баш, не ш.

Команда select используется не так часто. Проблема, с которой вы сталкиваетесь, заключается в том, что вы цепляете целые строки до $options с readarray, а команда select не предоставляет вам способ форматирования или обрезки вывода.

Один подход был бы разделить массив после его прочтения:

#!/usr/bin/env bash 

declare -a opt_host=() # Initialize our arrays, to make sure they're empty. 
declare -A opt_ip=()  # Note that associative arrays require Bash version 4. 
readarray -t options < ./file.txt 

for i in "${!options[@]}"; do 
    opt_host[$i]="${options[$i]%% *}"    # create an array of just names 
    opt_ip[${opt_host[$i]}]="${options[$i]#* }" # map names to IPs 
done 

PS3='Please enter your choice (q to quit): ' 
select host in "${opt_host[@]}"; do 
    case "$host" in 
    "") break ;; # This is a fake; any invalid entry makes $host=="", not just "q". 
    *) ssh "${opt_ip[$host]}" ;; 
    esac 
done 
+0

Спасибо большое! Это то, что я ищу. – thanksforanswer

+0

Его проблема связана не с 'options', а с его' read' командой, должным образом разделяющей выделение. – chepner

0

Ваш код правильный, но работать вокруг ошибки в bash 4.0, 4.1 и 4.2, необходимо процитировать расширение параметра в этой строке.

IFS=' ' read name ip <<< "$opt"