Làm cách nào để tạo menu trong tập lệnh shell sẽ hiển thị 3 tùy chọn mà người dùng sẽ sử dụng các phím mũi tên để di chuyển con trỏ tô sáng và nhấn enter để chọn một tùy chọn?
dialog
gói tạo giao diện đầu cuối giả-GUI cơ bản trong tập lệnh.
Làm cách nào để tạo menu trong tập lệnh shell sẽ hiển thị 3 tùy chọn mà người dùng sẽ sử dụng các phím mũi tên để di chuyển con trỏ tô sáng và nhấn enter để chọn một tùy chọn?
dialog
gói tạo giao diện đầu cuối giả-GUI cơ bản trong tập lệnh.
Câu trả lời:
Hộp thoại là một công cụ tuyệt vời cho những gì bạn đang cố gắng để đạt được. Dưới đây là ví dụ về menu 3 lựa chọn đơn giản:
dialog --menu "Choose one:" 10 30 3 \
1 Red \
2 Green \
3 Blue
Cú pháp như sau:
dialog --menu <text> <height> <width> <menu-height> [<tag><item>]
Các lựa chọn sẽ được gửi đến stderr
. Đây là một kịch bản mẫu sử dụng 3 màu.
#!/bin/bash
TMPFILE=$(mktemp)
dialog --menu "Choose one:" 10 30 3 \
1 Red \
2 Green \
3 Blue 2>$TMPFILE
RESULT=$(cat $TMPFILE)
case $RESULT in
1) echo "Red";;
2) echo "Green";;
3) echo "Blue";;
*) echo "Unknown color";;
esac
rm $TMPFILE
Trên Debian, bạn có thể cài đặt dialog
thông qua gói cùng tên .
Đây là một bash
giải pháp tập lệnh thuần túy dưới dạng select_option
hàm, chỉ dựa vào các chuỗi thoát ANSI và tích hợp sẵn read
.
Hoạt động trên Bash 4.2.45 trên OSX. Các phần thú vị có thể không hoạt động tốt như nhau trong tất cả các môi trường từ tất cả những gì tôi biết là get_cursor_row()
, key_input()
(để phát hiện các phím lên / xuống) và các cursor_to()
chức năng.
#!/usr/bin/env bash
# Renders a text based list of options that can be selected by the
# user using up, down and enter keys and returns the chosen option.
#
# Arguments : list of options, maximum of 256
# "opt1" "opt2" ...
# Return value: selected index (0 for opt1, 1 for opt2 ...)
function select_option {
# little helpers for terminal print control and key input
ESC=$( printf "\033")
cursor_blink_on() { printf "$ESC[?25h"; }
cursor_blink_off() { printf "$ESC[?25l"; }
cursor_to() { printf "$ESC[$1;${2:-1}H"; }
print_option() { printf " $1 "; }
print_selected() { printf " $ESC[7m $1 $ESC[27m"; }
get_cursor_row() { IFS=';' read -sdR -p $'\E[6n' ROW COL; echo ${ROW#*[}; }
key_input() { read -s -n3 key 2>/dev/null >&2
if [[ $key = $ESC[A ]]; then echo up; fi
if [[ $key = $ESC[B ]]; then echo down; fi
if [[ $key = "" ]]; then echo enter; fi; }
# initially print empty new lines (scroll down if at bottom of screen)
for opt; do printf "\n"; done
# determine current screen position for overwriting the options
local lastrow=`get_cursor_row`
local startrow=$(($lastrow - $#))
# ensure cursor and input echoing back on upon a ctrl+c during read -s
trap "cursor_blink_on; stty echo; printf '\n'; exit" 2
cursor_blink_off
local selected=0
while true; do
# print options by overwriting the last lines
local idx=0
for opt; do
cursor_to $(($startrow + $idx))
if [ $idx -eq $selected ]; then
print_selected "$opt"
else
print_option "$opt"
fi
((idx++))
done
# user key control
case `key_input` in
enter) break;;
up) ((selected--));
if [ $selected -lt 0 ]; then selected=$(($# - 1)); fi;;
down) ((selected++));
if [ $selected -ge $# ]; then selected=0; fi;;
esac
done
# cursor position back to normal
cursor_to $lastrow
printf "\n"
cursor_blink_on
return $selected
}
Dưới đây là một ví dụ sử dụng:
echo "Select one option using up/down keys and enter to confirm:"
echo
options=("one" "two" "three")
select_option "${options[@]}"
choice=$?
echo "Choosen index = $choice"
echo " value = ${options[$choice]}"
Đầu ra trông giống như bên dưới, với tùy chọn hiện được chọn được tô sáng bằng cách sử dụng màu ansi nghịch đảo (khó truyền tải ở đây trong phần đánh dấu). Điều này có thể được điều chỉnh trong print_selected()
chức năng nếu muốn.
Select one option using up/down keys and enter to confirm:
[one]
two
three
Cập nhật: Đây là một phần mở rộng nhỏ select_opt
gói select_option
chức năng trên để dễ sử dụng trong case
câu lệnh:
function select_opt {
select_option "$@" 1>&2
local result=$?
echo $result
return $result
}
Ví dụ sử dụng với 3 tùy chọn bằng chữ:
case `select_opt "Yes" "No" "Cancel"` in
0) echo "selected Yes";;
1) echo "selected No";;
2) echo "selected Cancel";;
esac
Bạn cũng có thể trộn nếu có một số mục đã biết (Có và Không trong trường hợp này) và tận dụng mã thoát $?
cho trường hợp ký tự đại diện:
options=("Yes" "No" "${array[@]}") # join arrays to add some variable array
case `select_opt "${options[@]}"` in
0) echo "selected Yes";;
1) echo "selected No";;
*) echo "selected ${options[$?]}";;
esac
tput
, nhưng tôi nghĩ rằng điều này là không thể), nhưng bạn có thể tạo các menu đơn giản trong bash vớiselect
: tldp.org/LDP/Bash-Beginners-Guide/html/sect_09_06.html