2016-03-07 49 views
1

我想做一個腳本來從文件中獲得ip列表並使用select選項在屏幕上顯示它,並通過選擇使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 shell中不存在。你確定這不是[tag:bash]問題嗎? – ghoti

+0

我的猜測是你在4.3之前使用的是'bash'版本,它有一個錯誤,要求在這個字符串中引用'$ opt'來分割才能正常發生。試試'IFS =''讀取名稱ip <<<「$ opt」'。 – chepner

+0

(爲了澄清,你的代碼應該在'bash' 4.3或更高版本中正常工作。) – chepner

回答

0

我假設這是bash的,而不是SH。

select命令不常用。您遇到的問題是,您將與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

你的代碼是正確的,但要解決一個bug在bash 4.0,4.1和4.2,則需要引用參數擴展在這裏的字符串。

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