有没有一种简单的方法可以让用户交互式地选择 的输出行
之一lsblk -f
?
NAME FSTYPE LABEL MOUNTPOINT
sda
├─sda1 ntfs WINRE_DRV
├─sda2 vfat SYSTEM_DRV
├─sda3 vfat LRS_ESP
├─sda4
├─sda5 ntfs Windows8_OS /media/Win8
├─sda6 ntfs Data /media/Data
├─sda7 ext4 linux /
├─sda8
├─sda9 ntfs 4gb-original
├─sda10 ntfs PBR_DRV
└─sda11 ext4 home /home
并让所选行填充到变量中以便在脚本的继续中使用?
我认为如果用户可以使用箭头键在各行中上下移动并按 Enter 键选择一个,那就完美了。 (我想我之前在安装过程中的一些配置脚本中已经看到过这一点。)如果这不可能,至少我如何在每行前面获取数字以让用户选择使用read
?
答案1
您正在寻找dialog
。它是一个非常强大的工具,用于ncurses
提供很多选项。我建议您仔细阅读它的联机帮助页。具体来说,您需要以下--menu
选项:
--menu text height width menu-height [ tag item ] ...
As its name suggests, a menu box is a dialog box that can be
used to present a list of choices in the form of a menu for the
user to choose. Choices are displayed in the order given. Each
menu entry consists of a tag string and an item string. The tag
gives the entry a name to distinguish it from the other entries
in the menu. The item is a short description of the option that
the entry represents. The user can move between the menu en‐
tries by pressing the cursor keys, the first letter of the tag
as a hot-key, or the number keys 1-9. There are menu-height en‐
tries displayed in the menu at one time, but the menu will be
scrolled if there are more entries than that.
On exit the tag of the chosen menu entry will be printed on dia‐
log's output. If the "--help-button" option is given, the cor‐
responding help text will be printed if the user selects the
help button.
不幸的是,由于各种引用问题,使用包含空格的命令的输出以合理的方式实现它是相当复杂的。无论如何,我没能做到这一点,不得不求助于使用eval
.尽管如此,它确实有效并且满足了您的要求:
#!/usr/bin/env bash
tmp=$(mktemp)
IFS=
eval dialog --menu \"Please choose a filesystem:\" 50 50 10 $(lsblk -f | sed -r 's/^/"/;s/$/" " "/' | tr $'\n' ' ') 2>$tmp
D=$(tr -d '│├└─' < $tmp | sed 's/^[ \t]*//' | cut -d' ' -f1)
printf "You chose:\n%s\n" "$D"
要获得更便携的方法,请将grep
命令更改为
justsed
格式化输出,lsblk
以便每个输出行周围都有引号(即对话框的“标签”),后跟带引号的空格(即对话框的“项目”),并tr
用空格和树部分字符替换换行符。
结果如下:
┌────────────────────────────────────────────────┐
│ Please choose a filesystem: │
│ ┌────────────────────────────────────────────┐ │
│ │ NAME FSTYPE LABEL MOUNTPOINT │ │
│ │ sda │ │
│ │ ├─sda1 │ │
│ │ ├─sda2 │ │
│ │ ├─sda3 /winblows │ │
│ │ ├─sda4 │ │
│ │ ├─sda5 │ │
│ │ ├─sda6 /home │ │
│ │ ├─sda7 / │ │
│ │ └─sda8 [SWAP] │ │
│ └────↓(+)────────────────────────────90%─────┘ │
│ │
├────────────────────────────────────────────────┤
│ < OK > <Cancel> │
└────────────────────────────────────────────────┘
答案2
在正常操作下,您无法更改光标上方的行——它们已经被刷新了。您可能看到的脚本可能使用了curses库,所以如果您真的想要这个,我建议使用像python这样的脚本语言并在那里使用curses库。
将数字放在每行前面要容易得多。您可以使用此 awk 行将数字放在它们前面。可能有一种更优雅的方法,但这可行。更改正则表达式以满足您的需求。
lsblk -f | awk 'BEGIN{disk=1;} /sd[a-z][1-9]+/ {print disk, ": ",$RT;disk=disk+1;next}{print " ", $RT}'