ITEEDU

9.6. 使用select内建命令来制作菜单

9.6.1. 概要

9.6.1.1. select的使用

select 结构可以生成简单的菜单。语法和 for 循环非常相似:

select WORD [in LIST]; do RESPECTIVE-COMMANDS; done

LIST 扩展开来,生成一个项目的列表。扩展后的内容被打印到标准错误;每个项目都以一个数字开始。如果 in LIST 不存在,位置参数就打印出来,the positional parameters are printed, as if in $@ would have been specified. LIST 只打印一次。

在打印所有项目的时候,PS3 提示被打印出来然后读取来自标准输入的一行。如果这行由那个项目的相关数字组成,那么 WORD 的值就设置成那个项目的名字。如果这行是空的,项目和 PS3 提示就再次显示出来。如果一个 EOF (End Of File) 字符被读取,循环就退出。既然多数用户ince most users don't have a clue which key combination is used for the EOF sequence, it is more user-friendly to have a break command as one of the items. Any other value of the read line will set WORD to be a null string.

读取的行存储在 REPLY 变量。

RESPECTIVE-COMMANDS 在每个选择之后执行直到读取了代表 break 的数字。退出循环。

9.6.1.2. 例子

这是一个非常简单的例子,但是正像你看到的,并不是特别的友好:

[carol@octarine testdir] cat private.sh
#!/bin/bash

echo "This script can make any of the files in this directory private."
echo "Enter the number of the file you want to protect:"

select FILENAME in *;
do
     echo "You picked $FILENAME ($REPLY), it is now only accessible to you."
     chmod go-rwx "$FILENAME"
done

[carol@octarine testdir] ./private.sh
This script can make any of the files in this directory private.
Enter the number of the file you want to protect:
1) archive-20030129
2) bash
3) private.sh
#? 1
You picked archive-20030129 (1)
#?

设置 PS3 提示且加入一个退出的可能性来做的更好:

#!/bin/bash

echo "This script can make any of the files in this directory private."
echo "Enter the number of the file you want to protect:"

PS3="Your choice: "
QUIT="QUIT THIS PROGRAM - I feel safe now."
touch "$QUIT"

select FILENAME in *;
do
  case $FILENAME in
        "$QUIT")
          echo "Exiting."
          break
          ;;
        *)
          echo "You picked $FILENAME ($REPLY)"
          chmod go-rwx "$FILENAME"
          ;;
  esac
done
rm "$QUIT"

9.6.2. 子菜单

任何 select 结构中的语句可以是另外一个 select 循环,通过菜单来启用子菜单。

默认,PS3 变量在进入嵌套 select 循环的时候没有改变。如果你想得到一个不同的提示,确定在适当的时机进行设置。