免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3172 | 回复: 2

[学习共享] 【原创】可以生成树形图的shell菜单 [复制链接]

论坛徽章:
0
发表于 2012-09-27 22:22 |显示全部楼层
用cygwin编写的,没在在其它系统上运行过:wink:

生成菜单树形图比较慢呵呵,不知道还有没有更好的算法,可能真正shell环境比cygwin快一些吧,不过好在生成树形图不是经常需要做的操作吧呵呵~

  1. #!/usr/bin/sh

  2. Enter()
  3. {
  4. echo
  5. printf "输入回车键继续..."
  6. read -s Enter
  7. echo
  8. }

  9. Chkfile()
  10. {
  11. if [ ! -f $1 ]
  12.    then
  13.         echo "ERR-0: 菜单文件 $1 不存在..."
  14.         exit 1
  15. fi
  16. }

  17. Chkinput()
  18. {
  19. if [ "x$2" = "xa" -o "x$2" = "xx" -o "x$2" = "xh" -o "x$2" = "xb" ]
  20.    then
  21.         return 0
  22. fi
  23. expr $2 + 0 >/dev/null 2>&1
  24. if [ $? -ne 0 ]
  25.    then
  26.         return 1
  27. fi
  28. if [ $2 -le 0 -o $2 -gt `awk 'END{print NR}' $1` ]
  29.    then
  30.         return 2
  31. fi
  32. }

  33. Tree()
  34. {
  35. menu=`expr $menu + 1`
  36. local i=1
  37. until [ $i -gt `awk 'END{print NR}' $1` ]
  38. do

  39.   echo $tree | awk '{for(i=1;i<="'$menu'";i++)if($i==1){printf "│  "}else{printf "    "}}'

  40.   if [ $verbose -eq 1 ]
  41.      then
  42.           text=`awk -F"$MENUCHAR" 'NR=="'$i'"{if($2!~/'$MENUTYPE'/){print $1"     "$2}else{print $1}}' $1`
  43.      else
  44.           text=`awk -F"$MENUCHAR" 'NR=="'$i'"{print $1}' $1`
  45.   fi

  46.   if [ $i -eq `awk 'END{print NR}' $1` ]
  47.      then
  48.          echo "└─$text"
  49.          tree=`echo $tree | awk '{for(i=1;i<=NF;i++){if(i==("'$menu'"+1))$i=0}}END{print $0}'`
  50.      else
  51.          echo "├─$text"
  52.          tree=`echo $tree | awk '{for(i=1;i<=NF;i++){if(i==("'$menu'")+1)$i=1}}END{print $0}'`
  53.   fi
  54.   run=`awk -F"$MENUCHAR" 'NR=="'$i'"{print $2}' $1`
  55.   if [ "`echo $run | awk -F"." '{print $NF}'`" = "$MENUTYPE" ]
  56.      then
  57.           tree="$tree 1"
  58.           Tree $MENUPATH/$run
  59.   fi
  60.   i=`expr $i + 1`
  61. done
  62. menu=`expr $menu - 1`
  63. }

  64. Menu()
  65. {

  66. menu=`expr $menu + 1`

  67. while true

  68. do

  69. if [ "x$input" = "xx" ]
  70.    then
  71.         exit
  72. fi

  73. clear

  74. echo
  75. echo "You can choose followed options:"
  76. echo
  77. echo "  ────────────────────────────"
  78. echo
  79. awk -F"$MENUCHAR" 'NF>1{printf "   "NR". ";if($2~/'$MENUTYPE'$/){printf "+ "}else{printf "* "}printf $1"\n\n"}' $1

  80. echo "  ────────────────────────────"
  81. echo

  82. if [ $menu -gt 1 ]
  83.    then
  84.        echo "   b Back     --- 返回上一级菜单"
  85.        echo
  86. fi
  87. echo "   a All      --- 全部执行"
  88. echo "   h Help     --- 帮助信息"
  89. echo "   x Exit     --- 退出"
  90. echo

  91. printf "Input your choice: "
  92. read input
  93. echo

  94. Chkinput $1 "$input"
  95. if [ $? -ne 0 ]
  96.    then
  97.         com=`echo $input | awk '{print $1}'`
  98.         which $com >/dev/null 2>&1
  99.         if [ $? -ne 0 ]
  100.         then
  101.              echo "ERR-1: 输入错误,请重新输入..."
  102.         else
  103.              eval $input
  104.         fi
  105.         Enter
  106.         continue
  107. fi

  108. case "$input" in

  109.       b) if [ $menu -ne 1 ]
  110.             then
  111.                  menu=`expr $menu - 1`
  112.                  return
  113.          fi
  114.          ;;

  115.       a)
  116.          awk -F"$MENUCHAR" 'BEGIN{
  117.                            a=0
  118.                           }
  119.                          {
  120.                            if($2!~/'$MENUTYPE'$/){
  121.                              print $1":";print "────────────────────"
  122.                              system($2)
  123.                              printf "\n"
  124.                              a+=1
  125.                              }
  126.                           }
  127.                       END{
  128.                            if(a==0)
  129.                               print "无可执行语句/脚本,请输入相应序号打开下级菜单"
  130.                          }' $1
  131.          Enter
  132.          ;;

  133.       h) echo "                帮助信息"
  134.          echo "───────────────────────"
  135.          echo
  136.          echo "    输入序号打开相应菜单/执行语句或脚本"
  137.          echo
  138.          echo "    序号后显示 + 号表示是有下级菜单"
  139.          echo "    序号后显示 * 号表示是可执行语句或脚本"
  140.          echo
  141.          echo "    a 执行所有菜单选项"
  142.          echo "    b 返回上一级菜单"
  143.          echo "    h 显示帮助信息"
  144.          echo "    x 退出"
  145.          echo
  146.          echo "───────────────────────"
  147.          Enter
  148.          ;;

  149.       x) exit
  150.          ;;

  151.       *) run=`awk -F"$MENUCHAR" 'NR=="'$input'"{print $2}' $1`
  152.          if [ "`echo $run | awk -F"." '{print $NF}'`" = "$MENUTYPE" ]
  153.             then
  154.                  if [ ! -f $MENUPATH/$run ]
  155.                     then
  156.                          echo "ERR-0: 菜单文件 $MENUPATH/$run 不存在..."
  157.                          Enter
  158.                     else
  159.                          Menu $MENUPATH/$run
  160.                  fi
  161.             else
  162.                  eval $run
  163.                  Enter
  164.          fi
  165.          ;;
  166. esac

  167. done

  168. }


  169. #================================#
  170. #            M A I N             #
  171. #================================#

  172. MENUPATH=$HOME/menu                     # 默认菜单文件存放路径
  173. MENUTYPE=menu                           # 菜单文件后缀名
  174. MENUFILE=$MENUPATH/TOOL.$MENUTYPE       # 默认打开的菜单文件
  175. MENUCHAR=%                              # 默认菜单文件分隔符


  176. menu=0 # 第几级菜单
  177. tree=0 # 默认不显示菜单树形图
  178. verbose=0 # 默认菜单树形图不显示详细菜单信息

  179. while getopts vtc:f:h OPTION
  180. do
  181.         case $OPTION in

  182.                 t)
  183.                    tree=1
  184.                    ;;
  185.                 v)
  186.                    verbose=1
  187.                    ;;
  188.                 f)
  189.                    MENUFILE=$MENUPATH/`echo $OPTARG | sed "s/\.$MENUTYPE$//"`.$MENUTYPE
  190.                    ;;
  191.                 h)
  192.                    echo
  193.                    echo "帮助信息"
  194.                    echo
  195.                    echo "Usage: `basename $0` [-t[-v]] [-h] [-c char] [-f file]"
  196.                    echo
  197.                    echo "-t, --Tree      显示菜单树形图"
  198.                    echo
  199.                    echo "-v, --Verbose   显示详细菜单树形图,需跟-t参数一起使用"
  200.                    echo
  201.                    echo "-c char         指定菜单文件中的分隔符"
  202.                    echo
  203.                    echo "-f file         打开指定菜单文件"
  204.                    echo
  205.                    echo "-h, --Help      显示帮助信息"
  206.                    echo
  207.                    exit
  208.                    ;;
  209.                 *)
  210.                    echo "请尝试执行\"`basename $0` -h\"来获取更多信息。"
  211.                    exit 1
  212.                    ;;
  213.         esac
  214. done

  215. if [ $tree -eq 1 ]
  216.    then
  217.         Chkfile $MENUFILE
  218.         tree=0
  219.         echo
  220.         echo "菜单列表"
  221.         Tree $MENUFILE
  222.    else
  223.         Chkfile $MENUFILE
  224.         Menu $MENUFILE
  225. fi
复制代码
执行效果:


  1. You can choose followed options:

  2.   ────────────────────────────

  3.    1. * PLSQL Developer

  4.    2. * SecureCRT

  5.    3. * UltraEdit

  6.   ────────────────────────────

  7.    a All      --- 全部执行
  8.    h Help     --- 帮助信息
  9.    x Exit     --- 退出

  10. Input your choice:

复制代码
使用说明:

修改脚本中以下变量定义菜单文件:

MENUPATH=$HOME/menu                               # 默认菜单文件存放路径
MENUTYPE=menu                                           # 菜单文件后缀名
MENUFILE=$MENUPATH/TOOL.$MENUTYPE       # 默认打开的菜单文件
MENUCHAR=%                                              # 默认菜单文件分隔符

然后按以上例子就是编辑菜单文件$HOME/menu/TOOL.menu,内容如下:

  1. PLSQL Developer%/cygdrive/d/Program\ Files/PLSQL\ Developer/plsqldev.exe &
  2. SecureCRT%/cygdrive/d/Tools/SecureCRT/SecureCRT.exe &
  3. UltraEdit%/cygdrive/d/Tools/UltraEdit/Uedit32.exe &
复制代码
%符号就是作为菜单标题和要执行命令(或脚本)的分隔符

如果想要加入子菜单,就再编写一个.menu文件,然后在这个%后面写上.menu文件即可

菜单文件全部编写好后,使用-t参数,可以生成菜单树形图,效果如下:

  1. 菜单列表
  2.     ├─系统状态检查
  3.     │  ├─系统状态检查
  4.     │  │  ├─文件系统使用率
  5.     │  │  ├─网络状态
  6.     │  │  ├─系统进程状态
  7.     │  │  └─占用内存进程TOP5
  8.     ├─数据库状态检查
  9.     │  ├─IMEX数据库
  10.     │  │  ├─数据库状态
  11.     │  │  ├─表空间使用率
  12.     │  │  ├─数据库session阻塞
  13.     │  │  └─导出Execl文件
  14.     │  └─影像数据库
  15.     │      ├─表空间使用率
  16.     │      ├─数据库锁
  17.     │      ├─正在运行的事务
  18.     │      ├─全表扫描的等待事件
  19.     │      └─数据库无效对象
  20.     └─生成报告
  21.         ├─晨检
  22.         ├─周报
  23.         └─月报
复制代码
-v 参数可以在树形图中将执行的命令(或脚本)显示出来(需要跟 -t 参数同时使用)

-f file 可以指定使用菜单文件

-c char 可以指定分隔符

-h 可以看使用帮助

论坛徽章:
0
发表于 2012-09-27 22:26 |显示全部楼层
本帖最后由 大红机器 于 2012-09-27 22:35 编辑

哦对了,选项前是 + 号说明是子菜单,* 号是可执行语句(或脚本)

另外选择的时候直接输入执行语句也可以~

论坛徽章:
0
发表于 2012-10-20 21:53 |显示全部楼层
生成树状菜单的代码改成awk,速度提高近10倍啊~

以下是tree.awk脚本
  1. #!/usr/bin/awk -f

  2. BEGIN{
  3. FS=MENUCHAR
  4. "awk 'END{print NR}' "filename |getline
  5. line=$1
  6. menu++
  7. }

  8. {
  9.   split(t,col,"#")
  10.   for(i=1;i<=menu;i++){
  11.       if(col[i]>0)
  12.          printf "│  "
  13.       if(col[i]==0)
  14.          printf "    "
  15.   }
  16.   if(NR==line){
  17.   print "└─"$1
  18.   col[menu+1]=0
  19.   t=col[1]
  20.   for(i=2;i<=menu+1;i++)t=t"#"col[i]
  21.   }
  22.   else{
  23.   print "├─"$1
  24.   col[menu+1]=1
  25.   t=col[1]
  26.   for(i=2;i<=menu+1;i++)t=t"#"col[i]
  27.   }
  28.   if($2~MENUTYPE"$"){
  29.   t=t"#"menu
  30.   menu=system("awk -v MENUTYPE="MENUTYPE" -v MENUCHAR="MENUCHAR" -v MENUPATH="MENUPATH" -v menu="menu" -v t="t" -v filename="MENUPATH"/"$2" -f tree.awk "MENUPATH"/"$2)
  31.   }
  32. }

  33. END{
  34. menu--
  35. exit menu
  36. }
复制代码
主脚本中Tree()函数改为
  1. awk -v MENUTYPE=$MENUTYPE -v MENUCHAR="$MENUCHAR" -v MENUPATH=$MENUPATH -v menu=$menu -v t=0 -v filename=$1 -f tree.awk $1
复制代码
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP