从动态列表创建交互式 Shell 提示菜单?
Create an interactive Shell prompt menu from a dynamic list?
下面的提示应该允许用户根据输出到数组的填充列表创建一个selection,然后打印列表及其索引,并要求用户select列表中的一个数字,然后将其设置为一个变量。只允许一个选择,如果用户指定了错误的选项,脚本将提示select一个正确的数字。
Multiple devices detected, please select one from the list:
1. Device1
2. Device2
3. Device3
1
You have selected device Device1
下面的代码不起作用并且有很多语法错误,首先我希望脚本检测 arr=($(ip ad|awk '/state UP/ {print }'))
的输出是否包含多个条目,如果是 运行 脚本,否则设置一个默认值。
case 语句不是动态的,但是,如果像下面这样的 case 超过 2 个,它将失败,也许是一个循环?
host_interfaces()
{
arr=($(ip ad|awk '/state UP/ {print }'))
echo "Multiple devices detected, please select one from the list:"
for i in "${!arr[@]}"; do
printf "%s%s\n" "$i. " "${arr[$i]}"
done
PS3='Please enter your choice: '
select opt in "${arr[@]}"
do
case $opt in
"$opt")
echo "You have selected device $opt"
export HOST_INTERFACE=$opt
;;
*) echo "invalid option
break
;;
esac
done
}
解决方案:
#! /bin/bash
declare HOST_INTERFACE=
function host_interfaces() {
local -a arr=($(ip ad | awk '/state UP/ {gsub(/:/, "", ); print }'))
if [ "${#arr[@]}" -eq 1 ]; then
HOST_INTERFACE="${arr[0]}"
return 0
fi
local opt=
HOST_INTERFACE=
echo "Multiple devices detected, please select one from the list:"
PS3='Please enter your choice: '
# Add "Quit" value to the items
select opt in "${arr[@]}" Quit; do
# "opt" does not contains the number but the associated value
case $opt in
"Quit")
#
break
;;
"")
# No value found
echo "invalid option"
;;
*)
echo "You have selected device $opt"
export HOST_INTERFACE=$opt
break
;;
esac
done
}
host_interfaces
也许是这个?
host_interfaces()
{
local opt='' h=''
arr=($(ip ad|awk '/state UP/ {print }'))
if [ "${#arr[@]}" -eq 1 ]; then
echo "One single device detected"
h="${arr[0]}"
elif [ "${#arr[@]}" -gt 1 ]; then
echo "Multiple devices detected, please select one from the list:"
PS3='Please enter your choice: '
select opt in "${arr[@]}"
do
case "$opt" in
"")
echo "Invalid choice"
h=''
;;
*)
echo "You have selected device $opt"
h="$opt"
break
;;
esac
done
else
echo "No device detected"
fi
echo "Selected device: ${h:-none}"
export HOST_INTERFACE="$h"
[ -z "$h" ] && return 1 || return 0
}
请注意函数 returns 1 如果没有找到或选择有效的设备,否则为 0。因此您可以将它用于:
if host_interfaces; then
echo "HOST_INTERFACE = $HOST_INTERFACE"
else
echo "No device selected"
fi
这里可以简单地使用dialog。
dialog --backtitle "Device selection" --title "Multiple devices detected" --menu "please select one from the list:" 10 45 4 1 "Device1" 2 "Device2" 3 "Device3"
见man dialog
下面的提示应该允许用户根据输出到数组的填充列表创建一个selection,然后打印列表及其索引,并要求用户select列表中的一个数字,然后将其设置为一个变量。只允许一个选择,如果用户指定了错误的选项,脚本将提示select一个正确的数字。
Multiple devices detected, please select one from the list:
1. Device1
2. Device2
3. Device3
1
You have selected device Device1
下面的代码不起作用并且有很多语法错误,首先我希望脚本检测 arr=($(ip ad|awk '/state UP/ {print }'))
的输出是否包含多个条目,如果是 运行 脚本,否则设置一个默认值。
case 语句不是动态的,但是,如果像下面这样的 case 超过 2 个,它将失败,也许是一个循环?
host_interfaces()
{
arr=($(ip ad|awk '/state UP/ {print }'))
echo "Multiple devices detected, please select one from the list:"
for i in "${!arr[@]}"; do
printf "%s%s\n" "$i. " "${arr[$i]}"
done
PS3='Please enter your choice: '
select opt in "${arr[@]}"
do
case $opt in
"$opt")
echo "You have selected device $opt"
export HOST_INTERFACE=$opt
;;
*) echo "invalid option
break
;;
esac
done
}
解决方案:
#! /bin/bash
declare HOST_INTERFACE=
function host_interfaces() {
local -a arr=($(ip ad | awk '/state UP/ {gsub(/:/, "", ); print }'))
if [ "${#arr[@]}" -eq 1 ]; then
HOST_INTERFACE="${arr[0]}"
return 0
fi
local opt=
HOST_INTERFACE=
echo "Multiple devices detected, please select one from the list:"
PS3='Please enter your choice: '
# Add "Quit" value to the items
select opt in "${arr[@]}" Quit; do
# "opt" does not contains the number but the associated value
case $opt in
"Quit")
#
break
;;
"")
# No value found
echo "invalid option"
;;
*)
echo "You have selected device $opt"
export HOST_INTERFACE=$opt
break
;;
esac
done
}
host_interfaces
也许是这个?
host_interfaces()
{
local opt='' h=''
arr=($(ip ad|awk '/state UP/ {print }'))
if [ "${#arr[@]}" -eq 1 ]; then
echo "One single device detected"
h="${arr[0]}"
elif [ "${#arr[@]}" -gt 1 ]; then
echo "Multiple devices detected, please select one from the list:"
PS3='Please enter your choice: '
select opt in "${arr[@]}"
do
case "$opt" in
"")
echo "Invalid choice"
h=''
;;
*)
echo "You have selected device $opt"
h="$opt"
break
;;
esac
done
else
echo "No device detected"
fi
echo "Selected device: ${h:-none}"
export HOST_INTERFACE="$h"
[ -z "$h" ] && return 1 || return 0
}
请注意函数 returns 1 如果没有找到或选择有效的设备,否则为 0。因此您可以将它用于:
if host_interfaces; then
echo "HOST_INTERFACE = $HOST_INTERFACE"
else
echo "No device selected"
fi
这里可以简单地使用dialog。
dialog --backtitle "Device selection" --title "Multiple devices detected" --menu "please select one from the list:" 10 45 4 1 "Device1" 2 "Device2" 3 "Device3"
见man dialog