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 的数字。退出循环。
这是一个非常简单的例子,但是正像你看到的,并不是特别的友好:
[carol@octarine testdir]
catprivate.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"