# 图形化桌面环境的shell文本菜单

前面介绍的shell脚本都是文本编辑的指令,如果想在图形化环境中运行脚本,有很多可以让交互式脚本更友好的方法,一种最简单的就是创建文本菜单。

# 1)文本菜单布局设计

菜单脚本会清空显示区域,然后显示可用的选项列表。用户可以按下与每个选项关联的字母或数字来选择选项。

shell脚本菜单的核心是case命令,case命令会根据用户在菜单上的选择来执行特定命令。

clear 命令用当前终端会话的terminfo数据来清理出现在屏幕上的文本。运行clear命令之后,可以用echo命令来显示菜单元素。默认情况下,echo 命令只显示可打印文本字符。要在 echo 命令中包含如制表符和换行符这些非可打印字符,必须用 -e 选项。

echo -e "1.\tDisplay disk space"
# 1.	Display disk space

只需要几个 echo 命令,就能创建一个菜单项布局的格式化。如:

clear
echo
echo -e "\t\t\tSys Admin Menu\n"
echo -e "\t1. Display disk space"
echo -e "\t2. Display logged on users"
echo -e "\t3. Display memory usage"
echo -e "\t0. Exit menu\n\n"
echo -en "\t\tEnter option: "

创建菜单布局后再加上获取用户输入的命令:

read -n 1 option

这样执行后,菜单就会显示在终端上,并一直等待用户输入:

$ ./test.sh
# Sys Admin Menu

# 	1. Display disk space
# 	2. Display logged on users
# 	3. Display memory usage
# 	0. Exit menu


# 		Enter option: 

# 2)创建菜单函数

设计好布局后,shell脚本菜单选项作为一组独立的函数实现起来更为容易,现在来为每个菜单选项创建独立的shell函数。

通常会为还没有实现的函数先创建一个桩函数(stub function)。桩函数是一个空函数,或者只有一个 echo 语句,说明最终这里里需要什么内容。

function diskspace_func {
    clear
    echo "This is where the disk space commands will go"
}
function login_user_func {
    clear
    echo "This is where the logged on users commands will go"
}
function memusage_func {
    clear
    echo "This is where the mem usage commands will go"
}

# 3)定义菜单逻辑

建好菜单布局和函数后,就需要设置菜单逻辑了,这需要用到 case 命令。case 命令应该根据菜单中输入的字符来调用相应的函数。

menu
case $option in
    0)
    break ;;
    1)
        diskspace_func ;;
    2)
        login_user_func ;;
    3)
        memusage_func ;;
    *)
        clear
        echo "Sorry, wrong selection";;
esac

综合以上的逻辑,最后完整的脚本为:

#!/bin/bash

function menu {
    clear
    echo
    echo -e "\t\t\tSys Admin Menu\n"
    echo -e "\t1. Display disk space"
    echo -e "\t2. Display logged on users"
    echo -e "\t3. Display memory usage"
    echo -e "\t0. Exit menu\n\n"
    echo -en "\t\tEnter option: "
    read -n 1 option
}

function diskspace_func {
    clear
    echo "This is where the disk space commands will go"
}
function login_user_func {
    clear
    echo "This is where the logged on users commands will go"
}
function memusage_func {
    clear
    echo "This is where the mem usage commands will go"
}

while [ 1 ]
do 
menu
case $option in
    0)
    break ;;
    1)
        diskspace_func ;;
    2)
        login_user_func ;;
    3)
        memusage_func ;;
    *)
        clear
        echo "Sorry, wrong selection";;
    esac
    echo -en "\n\n\t\t\tHit any key to continue"
    read -n 1 line
done
clear

上面的脚本中echo -en是输出非打印字符,其中n表示不换行。上面的脚本,只有在输入的option0的时候,才会退出循环。

# 4)使用select命令

从上面的例子中可以看到创建文本菜单的一半工夫都花在了建立菜单布局和获取用户输入,bash shell提供了一个很容易上手的小工具,来帮助用户自动完成这些工作。

select 命令只需要一条命令就可以创建出菜单,然后获取输入的答案并自动处理。 select
命令的格式如下:

select variable in list
do
    commands
done

list 参数是由空格分隔的文本选项列表,这些列表构成了整个菜单。 select 命令会将每个
列表项显示成一个带编号的选项,然后为选项显示一个由 PS3 环境变量定义的特殊提示符。

使用 select 命令时,记住,存储在变量中的结果值是整个文本字符串而不是跟菜单选项,相关联的数字。文本字符串值才是要在 case 语句中进行比较的内容。

使用select命令,对上面的例子进行改写的结果为:

#!/bin/bash

function diskspace_func {
    clear
    echo "This is where the disk space commands will go"
}
function login_user_func {
    clear
    echo "This is where the logged on users commands will go"
}
function memusage_func {
    clear
    echo "This is where the mem usage commands will go"
}

while [ 1 ]
do 
    PS3="Enter option: "
    select option in "Display disk space" "Display logged on users" "Display memory usage" "Exit program"
    do
        case $option in
        "Exit program")
            break ;;
        "Display disk space")
            diskspace_func ;;
        "Display logged on users")
            login_user_func ;;
        "Display memory usage")
            memusage_func ;;
        *)
            clear
            echo "Sorry, wrong selection";;
        esac
        echo -en "\n\n\t\t\tHit any key to continue"
        read -n 1 line
    done
done
clear

可以看到使用select语句可以省略掉创建菜单布局的文本。

(adsbygoogle = window.adsbygoogle || []).push({});