select 结构可以方便地生成菜单。其语法与 for 循环非常相似
selectWORD[inLIST]; do RESPECTIVE-COMMANDS; done
LIST会被展开,生成一个项目列表。展开结果会打印到标准错误输出;每个项目前面都有一个数字。如果 in LIST 不存在,则会打印位置参数,就像指定了 in $@ 一样。LIST只打印一次。
在打印完所有项目后,PS3提示符会被打印,并从标准输入读取一行。如果这行包含一个与其中一个项目对应的数字,则会将WORD设置为该项目的名称。如果该行是空的,项目和PS3提示符会再次显示。如果读取到 EOF (文件结束) 字符,循环会退出。由于大多数用户不知道 EOF 序列使用哪个组合键,因此最好将 break 命令作为其中一个项目,这样更方便用户。读取行的任何其他值都会将WORD设置为空字符串。
读取的行保存在REPLY变量中。
在每次选择后,会执行 RESPECTIVE-COMMANDS,直到读取到代表 break 的数字。这将退出循环。
这是一个非常简单的例子,但正如你所看到的,它不是很用户友好
[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" |