我正在尝试创建一个脚本来运行命令并获取该输出并使用它来动态创建菜单。我还需要访问每个输出行的部分以获得特定值。
我正在使用命令:
lsblk --nodeps -no name,serial,size | grep "sd"
输出:
sda 600XXXXXXXXXXXXXXXXXXXXXXXXXX872 512G
sdb 600XXXXXXXXXXXXXXXXXXXXXXXXXXf34 127G
我需要创建一个如下所示的菜单:
Available Drives:
1) sda 600XXXXXXXXXXXXXXXXXXXXXXXXXX872 512G
2) sdb 600XXXXXXXXXXXXXXXXXXXXXXXXXXf34 127G
Please select a drive:
(注意:可以有任意数量的驱动器,此菜单将从可用驱动器数组动态构建)
当用户选择菜单编号时,我需要能够访问所选驱动器的驱动器 ID (sdb) 和驱动器序列号 (600XXXXXXXXXXXXXXXXXXXXXXXXXXf34)。
如有任何帮助,我们将不胜感激。 如果需要任何说明,请告诉我。
最佳答案
#!/usr/bin/env bash
# Read command output line by line into array ${lines [@]}
# Bash 3.x: use the following instead:
# IFS=$'\n' read -d '' -ra lines < <(lsblk --nodeps -no name,serial,size | grep "sd")
readarray -t lines < <(lsblk --nodeps -no name,serial,size | grep "sd")
# Prompt the user to select one of the lines.
echo "Please select a drive:"
select choice in "${lines[@]}"; do
[[ -n $choice ]] || { echo "Invalid choice. Please try again." >&2; continue; }
break # valid choice was made; exit prompt.
done
# Split the chosen line into ID and serial number.
read -r id sn unused <<<"$choice"
echo "id: [$id]; s/n: [$sn]"
至于您的尝试:在数组构造函数 (( ... )
) 中使用不带引号的命令替换 ($(...)
) 生成标记在命令的输出中进行分词和通配,这意味着,默认情况下,每个以空格分隔的标记成为它自己的数组元素,并且可以扩展为匹配的文件名。
以这种方式填充数组是脆弱的,即使您可以通过设置 IFS
并关闭 globbing (set -f
) 来解决这个问题,更好的方法是使用 readarray -t
(Bash v4+) 或 IFS=$'\n' read -d '' -ra
(Bash v3.x) 和进程替换来填充一个包含命令输出的(未修改的)行的数组。
关于bash 脚本 : use command output to dynamically create menu and arrays?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40558976/