Per*_*ulf 2 ncurses shell-script terminfo
假设您TUI
在 shell 中显示以下内容:
我需要一组可以在 shell 中使用的库来完成它。可以肯定的是,ncurses
还没有被使用,因为它产生了依赖。
问题:如何TUI
在 shell 中构建小部件/窗口或其他?
好的,我觉得你可能会问两个问题之一,所以我会尽量回答这两个问题。
可以使用哪些库来为 shell 脚本创建类似 ncurses 的接口?
实际上,无论如何,我永远不会直接为 shell 脚本推荐 ncurses,因为它真的不打算被 shell 语言使用。相反,我会推荐dialog
. Dialog 是一个 shim 库,位于 ncurses 和 shell 之间,使其使用更加简单。
这将在功能上为您提供两个依赖项(一个 onncurses
和一个 on dialog
),您似乎出于某种原因反对它们。
鉴于我不想要任何外部依赖项,我如何创建自己的类似 ncurses 的 TUI 库?
这是方式* nix.SE的范围之内。创建一个新的 TUI 库绝非易事(尤其是当您尝试在纯 shell 中创建它时)。已经有很多项目试图创建新的库来替代 ncurses 的一些使用(例如,termbox
是更成功的项目之一)。
如果您打算创建自己的库,您可能需要查看较低级别的项目(如 ncurses 和 termbox)和较高级别的项目(如对话框)。看看他们的工作可能会让你知道如何开始。
最后的建议:
对外部项目的依赖,虽然它们需要一些额外的工作(用于集成和支持),但并不是一件坏事。这意味着您可以只专注于您想要制作的工具,而将基础工作留给那些从事较低基础设施的人。Linux,尤其是在 *nix 平台之外,有着悠久的依赖交互历史。
如果您的目标是了解较低级别的工作是如何完成的,那么就去做吧。相反,如果您正在尝试制作一个可以从这种低级工作中受益的工具,只需依赖外部工具即可。你会更快乐,每个人都会看到你的代码。
小智 6
#/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
Run Code Online (Sandbox Code Playgroud)