如何创建基于终端的GUI?


50

我正在寻找一个基于终端的环境,以适应我的Bash脚本。我希望它看起来像这样:

Debian安装


4
查看dialog,这似乎是要使用的。
DopeGhoti


我认为基于终端的GUI是TUI(与CLI不同)。
UniversallyUniqueID

“ tui”是RH术语IIRC。whiptail> dialog
布拉奇利(Bratchley)'16

@Bratchley:GDB还在tui其分割窗口模式下使用layout reg例如,显示寄存器,源代码和命令,并tui reg vec在reg窗口中显示矢量寄存器(以一种不灵活的方式,因此该部分并不是真正有用的:/)。 IDK,如果Redhat编写了添加该功能的补丁,甚至是该功能有多旧
彼得·科德斯

Answers:


42
dialog --backtitle "Package configuration" \
       --title "Configuration sun-java-jre" \
       --yesno "\nBla bla bla...\n\nDo you accept?" 10 30

在此处输入图片说明

用户响应存储在退出代码中,因此可以照常打印:(echo $?请注意,在外壳程序世界中0,其含义为“是”,而其含义为“否” 1)。


关于评论部分的其他问题:

  • 要将某些命令的输出放到对话框中,只需使用命令替换机制即可$(),例如:

     dialog --backtitle "$(echo abc)" --title "$(cat file)" ...
    
  • 为用户提供多种选择,您可以使用--menuoption代替--yesno

  • 要将用户选择的输出存储到变量中,需要使用--stdoutoption或通过--output-fd或手动更改输出描述符,例如:

    output=$(dialog --backtitle "Package configuration" \
                    --title "Configuration sun-java-jre" \
                    --menu "$(parted -l)" 15 40 4 1 "sda1" 2 "sda2" 3 "sda3" \
             3>&1 1>&2 2>&3 3>&-)
    echo "$output"
    

    之所以需要此技巧,是因为dialog默认情况下输出到stderr,而不是stdout。

和往常一样,man dialog是您的朋友。


多数民众赞成在美丽的“ bla bla bla ...”,但您如何捕获输出?
tempfor在树林中找到我

1
@tempforFindMeInTheWoods如果通过输出表示退出代码,则照常进行:将其存储在?变量中,请尝试echo $?
jimmij

1
@tempforFindMeInTheWoods如果要parted -l通过对话框向用户显示命令的输出,则选择选项可能--menu是一个更好的选择-yesno。在这种情况下,您将不得不使用一些描述符来将输出存储到变量中,例如:output=$(dialog --backtitle "Package configuration" --title "Configuration sun-java-jre" --menu "$(parted -l)" 15 40 4 1 "sda1" 2 "sda2" 3 "sda3" 3>&1 1>&2 2>&3 3>&-); echo $output
jimmij

3
或者,您可以使用该--stdout选项。
Thomas Dickey

2
手册中说明了所有对话框选项:man dialog
Ferrybig '16

34

问题中的屏幕快照看起来像是whetail(功能简化的模仿对话框的程序,使用newt而不是ncurses)。标题和按钮的呈现方式内置于每个程序中,使它们看起来有所不同。

这是一个脚本,该脚本复制了原始的屏幕快照,无论是用于鞭打还是对话框:

#!/bin/sh
: ${DIALOG:=dialog}
case "$DIALOG" in
*dialog*)
        OPTS="$OPTS --cr-wrap"
        high=10
        ;;
*whiptail*)
        high=12
        ;;
esac
rows=$(stty size | cut -d' ' -f1)
[ -z "$rows" ] && rows=$high
[ $rows -gt $high ] && rows=$high
cols=$(stty size | cut -d' ' -f2)
$DIALOG --backtitle "Package configuration" \
       --title "Configuring sun-java6-jre" \
       $OPTS \
       --yesno '\nIn order to install this package, you must accept the license terms, the "Operating System Distributor License for Java" (DLJ), v1.1. Not accepting will cancel the installation.\n\nDo you accept the DLJ license terms?' $rows $((cols - 5))

为了进行比较,用鞭子截图:

屏幕截图

并带有对话框:

对话框截图

除了标题和按钮的外观不同之外,对话框默认情况下还使用不同的颜色(尽管这是可配置的,请参阅屏幕截图),并且在屏幕上使用的行数更少。

对话框(和鞭子)使用库来管理线条,颜色等的显示。但是您也可能会在Red Hat anaconda程序中使用newt作为从python调用的共享库(外观相同)。同样,内核配置程序从对话框的(缩减的)副本开始,然后使用共享库(没有原始lxdialog程序)演变为功能,就像从python使用newt一样。

从bash开始-您可以将对话框或鞭打用于最常用的功能。有人为这些脚本(在perl中)编写了一个包装器,以允许脚本更容易地使用这些脚本或其他脚本,但是您最好直接使用对话框,因为perl模块本质上是公分母。

对话框源包括所有小部件的示例以及大多数命令行选项:

cdialog (ComeOn Dialog!) version 1.3-20160424
Copyright 2000-2015,2016 Thomas E. Dickey
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

* Display dialog boxes from shell scripts *

Usage: cdialog <options> { --and-widget <options> }
where options are "common" options, followed by "box" options

Special options:
  [--create-rc "file"]
Common options:
  [--ascii-lines] [--aspect <ratio>] [--backtitle <backtitle>] [--beep]
  [--beep-after] [--begin <y> <x>] [--cancel-label <str>] [--clear]
  [--colors] [--column-separator <str>] [--cr-wrap] [--date-format <str>]
  [--default-button <str>] [--default-item <str>] [--defaultno]
  [--exit-label <str>] [--extra-button] [--extra-label <str>]
  [--help-button] [--help-label <str>] [--help-status] [--help-tags]
  [--hfile <str>] [--hline <str>] [--ignore] [--input-fd <fd>]
  [--insecure] [--item-help] [--keep-tite] [--keep-window] [--last-key]
  [--max-input <n>] [--no-cancel] [--no-collapse] [--no-cr-wrap]
  [--no-items] [--no-kill] [--no-label <str>] [--no-lines] [--no-mouse]
  [--no-nl-expand] [--no-ok] [--no-shadow] [--no-tags] [--nook]
  [--ok-label <str>] [--output-fd <fd>] [--output-separator <str>]
  [--print-maxsize] [--print-size] [--print-version] [--quoted]
  [--scrollbar] [--separate-output] [--separate-widget <str>] [--shadow]
  [--single-quoted] [--size-err] [--sleep <secs>] [--stderr] [--stdout]
  [--tab-correct] [--tab-len <n>] [--time-format <str>] [--timeout <secs>]
  [--title <title>] [--trace <file>] [--trim] [--version] [--visit-items]
  [--week-start <str>] [--yes-label <str>]
Box options:
  --buildlist    <text> <height> <width> <list-height> <tag1> <item1> <status1>...
  --calendar     <text> <height> <width> <day> <month> <year>
  --checklist    <text> <height> <width> <list height> <tag1> <item1> <status1>...
  --dselect      <directory> <height> <width>
  --editbox      <file> <height> <width>
  --form         <text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1>...
  --fselect      <filepath> <height> <width>
  --gauge        <text> <height> <width> [<percent>]
  --infobox      <text> <height> <width>
  --inputbox     <text> <height> <width> [<init>]
  --inputmenu    <text> <height> <width> <menu height> <tag1> <item1>...
  --menu         <text> <height> <width> <menu height> <tag1> <item1>...
  --mixedform    <text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1> <itype>...
  --mixedgauge   <text> <height> <width> <percent> <tag1> <item1>...
  --msgbox       <text> <height> <width>
  --passwordbox  <text> <height> <width> [<init>]
  --passwordform <text> <height> <width> <form height> <label1> <l_y1> <l_x1> <item1> <i_y1> <i_x1> <flen1> <ilen1>...
  --pause        <text> <height> <width> <seconds>
  --prgbox       <text> <command> <height> <width>
  --programbox   <text> <height> <width>
  --progressbox  <text> <height> <width>
  --radiolist    <text> <height> <width> <list height> <tag1> <item1> <status1>...
  --rangebox     <text> <height> <width> <min-value> <max-value> <default-value>
  --tailbox      <file> <height> <width>
  --tailboxbg    <file> <height> <width>
  --textbox      <file> <height> <width>
  --timebox      <text> <height> <width> <hour> <minute> <second>
  --treeview     <text> <height> <width> <list-height> <tag1> <item1> <status1> <depth1>...
  --yesno        <text> <height> <width>

Auto-size with height and width = 0. Maximize with height and width = -1.
Global-auto-size if also menu_height/list_height = 0.

进一步阅读:


11

我相信您正在寻找的软件包是ncurses

维基百科对ncurses的描述如下:

ncurses(新的curses)是一个编程库,提供了API,允许程序员以与终端无关的方式编写基于文本的用户界面。它是用于开发在终端仿真器下运行的“类似于GUI”的应用程序软件的工具包

它被广泛使用,例如,在menuconfig内核配置工具中: Linux内核menuconfig工具的屏幕截图

由于您正在使用bash,因此可以使用Bash简单诅咒(如Runium在下面的注释中所述)。


11
ncurses是一个C库。(如果我理解正确的话)OP需要一个脚本环境(用于bash)。menuconfig用C语言编写。作为的替代方案 dialog,您可能还可以提及Bash简单诅咒,它是用bash编写的(依赖tput)。
鲁尼姆'16

@Runium:感谢您的澄清和指向Bash简单诅咒的链接。
Thawn

2
不过,值得一提的是这ncurses是基础,它回答了这个问题的更一般版本……就像这里标题中的那个一样:)
underscore_d

-1

善意

zenity --file-selection --directory

# var means variable

var\
=$(
zenity --entry                   \
       --title="title"           \
       --text="text"             \
       --entry-text="entry text" \ 
)                                \
&&
echo "$var"

# ls is a command to list files in a directory

ls $(zenity --file-selection --directory)

带有选项的zenity对话框条目

password=$(zenity --password)

zenity-密码

file="$(zenity --file-selection)"

zenity-文件选择

zenity --help

zenity-帮助结果

zenity --help-general 

zenity-帮助-一般结果

zenity --help-entry

zenity-帮助输入结果

其他图形用户界面(gui)

dialog

对话

dialog                               \
 --backtitle "backtitle"             \
 --title "title"                     \
 --yesno                             \
 "bla bla bla...\n\n Do you accept?" \
 0 -1                                
echo $?

停止进一步执行脚本,将其中断。行:echo $?, 永远不会发生

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.