2016-03-07 48 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"