shell 脚本中的一组库,例如 ncurses

shell 脚本中的一组库,例如 ncurses

TUI假设您在 shell 中显示以下内容:

在此输入图像描述

我需要一组可以在 shell 中使用的库来完成此操作。可以肯定的是,ncurses还没有使用过,因为它产生了依赖。

问题:如何TUI在 shell 中构建小部件/窗口或其他部件?

答案1

好吧,我觉得你可能会问两个问题之一,所以我会尽力回答这两个问题。

  1. 可以使用哪些库来为 shell 脚本创建类似于 ncurses 的接口?

    事实上,我永远不会直接推荐 ncurses 用于 shell 脚本,因为它实际上并不适合由 shell 语言使用。相反,我会推荐dialog。 Dialog 是一个垫片库,位于 ncurses 和 shell 之间,使其使用更加简单。

    这将在功能上为您提供两个依赖项(一个 onncurses和一个 on dialog),您似乎出于某种原因反对它们。

  2. 鉴于我不需要任何外部依赖项,我如何创建自己的类似 ncurses 的 TUI 库?

    这是方式超出 *nix.SE 的范围。创建新的 TUI 库并非易事(特别是如果您尝试在纯 shell 中创建它)。有很多项目尝试创建新的库来取代 ncurses 的一些使用(例如,termbox是比较成功的之一)。

    如果您打算创建自己的库,您可能需要查看 ncurses 和 termbox 等较低级别的项目以及dialog 等较高级别的项目。看看他们的工作可能会让您了解如何开始。


最后的建议:

对外部项目的依赖,尽管它们需要一些额外的工作(用于集成和支持)不是一件坏事。这意味着您可以只专注于您想要制作的工具,并将基础工作留给从事较低基础设施的人员。 Linux,特别是 *nix 平台之外的,具有悠久的依赖交互历史。

如果您的目标是了解较低级别的内容是如何完成的,那么就去吧。相反,如果您试图创建一个可以从如此低水平的工作中受益的工具,那么只需依赖外部工具即可。您会更高兴,每个查看您的代码的人也会更高兴。

答案2

#/bin/bash
      E='echo -e';e='echo -en';trap "R;exit" 2
    ESC=$( $e "\e")
   TPUT(){ $e "\e[${1};${2}H";}
  CLEAR(){ $e "\ec";}
  CIVIS(){ $e "\e[?25l";}
   DRAW(){ $e "\e%@\e(0";}
  WRITE(){ $e "\e(B";}
   MARK(){ $e "\e[7m";}
 UNMARK(){ $e "\e[27m";}
      R(){ CLEAR ;stty sane;$e "\ec\e[37;44m\e[J";};
   HEAD(){ DRAW
           for each in $(seq 1 13);do
           $E "   x                                          x"
           done
           WRITE;MARK;TPUT 1 5
           $E "BASH SELECTION MENU                       ";UNMARK;}
           i=0; CLEAR; CIVIS;NULL=/dev/null
   FOOT(){ MARK;TPUT 13 5
           printf "ENTER - SELECT,NEXT                       ";UNMARK;}
  ARROW(){ read -s -n3 key 2>/dev/null >&2
           if [[ $key = $ESC[A ]];then echo up;fi
           if [[ $key = $ESC[B ]];then echo dn;fi;}
     M0(){ TPUT  4 20; $e "Login info";}
     M1(){ TPUT  5 20; $e "Network";}
     M2(){ TPUT  6 20; $e "Disk";}
     M3(){ TPUT  7 20; $e "Routing";}
     M4(){ TPUT  8 20; $e "Time";}
     M5(){ TPUT  9 20; $e "ABOUT  ";}
     M6(){ TPUT 10 20; $e "EXIT   ";}
      LM=6
   MENU(){ for each in $(seq 0 $LM);do M${each};done;}
    POS(){ if [[ $cur == up ]];then ((i--));fi
           if [[ $cur == dn ]];then ((i++));fi
           if [[ $i -lt 0   ]];then i=$LM;fi
           if [[ $i -gt $LM ]];then i=0;fi;}
REFRESH(){ after=$((i+1)); before=$((i-1))
           if [[ $before -lt 0  ]];then before=$LM;fi
           if [[ $after -gt $LM ]];then after=0;fi
           if [[ $j -lt $i      ]];then UNMARK;M$before;else UNMARK;M$after;fi
           if [[ $after -eq 0 ]] || [ $before -eq $LM ];then
           UNMARK; M$before; M$after;fi;j=$i;UNMARK;M$before;M$after;}
   INIT(){ R;HEAD;FOOT;MENU;}
     SC(){ REFRESH;MARK;$S;$b;cur=`ARROW`;}
     ES(){ MARK;$e "ENTER = main menu ";$b;read;INIT;};INIT
  while [[ "$O" != " " ]]; do case $i in
        0) S=M0;SC;if [[ $cur == "" ]];then R;$e "\n$(w        )\n";ES;fi;;
        1) S=M1;SC;if [[ $cur == "" ]];then R;$e "\n$(ifconfig )\n";ES;fi;;
        2) S=M2;SC;if [[ $cur == "" ]];then R;$e "\n$(df -h    )\n";ES;fi;;
        3) S=M3;SC;if [[ $cur == "" ]];then R;$e "\n$(route -n )\n";ES;fi;;
        4) S=M4;SC;if [[ $cur == "" ]];then R;$e "\n$(date     )\n";ES;fi;;
        5) S=M5;SC;if [[ $cur == "" ]];then R;$e "\n$($e by oTo)\n";ES;fi;;
        6) S=M6;SC;if [[ $cur == "" ]];then R;exit 0;fi;;
 esac;POS;done

相关内容