Wie erstelle ich eine terminalbasierte Benutzeroberfläche?

50

Ich möchte eine Terminal-basierte Umgebung erstellen, in die ich mein Bash- Skript anpassen kann . Ich möchte, dass es so aussieht:

Debian installieren

tempforFinde mich im Wald
quelle
4
Schauen Sie sich an dialog, was dies zu verwenden scheint.
DopeGhoti
Ich denke, eine Terminal-basierte Benutzeroberfläche ist eine TUI (die sich von der CLI unterscheidet).
UniversallyUniqueID
"tui" ist ein RH-Begriff IIRC. whiptail> dialogauch
Bratchley
@Bratchley: GDB wird auch tuifür den geteilten Fenstermodus verwendet ( layout regz. B. tui reg veczum Anzeigen von Registern, Quellen und Befehlen sowie zum Anzeigen von Vektorregistern im Reg-Fenster (auf nicht flexible Weise, sodass dieser Teil nicht wirklich nützlich ist: /). IDK, ob Redhat den Patch geschrieben hat, der diese Funktion hinzugefügt hat, oder wie alt sie ist
Peter Cordes,

Antworten:

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

Bildbeschreibung hier eingeben

Die Benutzerantwort wird im Exit-Code gespeichert und kann wie gewohnt gedruckt werden: echo $?(Beachten Sie, dass 0dies 1in der Shell-Welt "Ja" und "Nein" bedeutet.)


Zu weiteren Fragen aus dem Kommentarbereich:

  • Um die Ausgabe eines Befehls in das Dialogfeld einzufügen, verwenden Sie einfach den Befehlssubstitutionsmechanismus $(), z.

     dialog --backtitle "$(echo abc)" --title "$(cat file)" ...
    
  • Um dem Benutzer mehrere Auswahlmöglichkeiten zu geben, können Sie die --menuOption anstelle von verwenden--yesno

  • Um die Ausgabe der Benutzerauswahl in einer Variablen zu speichern, muss die --stdoutOption verwendet oder der Ausgabedeskriptor entweder über --output-fdoder manuell geändert werden, z. B .:

    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"
    

    Dieser Trick wird benötigt, da dialogstandardmäßig stderr und nicht stdout ausgegeben wird.

Und wie immer man dialogist dein Freund.

jimmij
quelle
Das ist wunderschön "Bla bla bla ...", aber wie erfassen Sie die Ausgabe?
tempforFind Me In The Woods
1
@tempforFindMeInTheWoods Wenn mit Ausgabe Exit-Code gemeint ist, dann genauso: Es wird in einer ?Variablen gespeichert . Versuchen Sie es echo $?.
Jimmy
1
@tempforFindMeInTheWoods Wenn Sie parted -ldem Benutzer die Ausgabe des Befehls über ein Dialogfeld anzeigen möchten, --menuist die Option wahrscheinlich die bessere Wahl als -yesno. In einem solchen Fall müssten Sie ein bisschen mit Deskriptoren spielen, um die Ausgabe in der Variablen zu speichern, zum Beispiel: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
Oder Sie könnten die --stdoutOption verwenden.
Thomas Dickey
2
Alle Dialogoptionen werden im Handbuch erklärt:man dialog
Ferrybig
34

Der Screenshot in der Frage sieht aus wie whiptail (funktionsreduzierten Programm Imitieren Dialog , mit Molche statt ncurses ). Die Art und Weise, wie Titel und Schaltflächen gerendert werden, ist in jedes Programm integriert, sodass sie unterschiedlich aussehen.

Hier ist ein Skript, das den Original-Screenshot für Whiptail oder Dialog dupliziert:

#!/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))

und zum Vergleich Screenshot mit Whiptail:

Screenshot mit Peitschenschwanz

und mit dialog:

Screenshot mit Dialog

Neben dem unterschiedlichen Erscheinungsbild von Titel und Schaltflächen werden im Dialogfeld standardmäßig andere Farben verwendet (obwohl dies konfigurierbar ist - siehe Screenshots ) und weniger Zeilen auf dem Bildschirm.

dialog (und whiptail) verwenden Bibliotheken, um die Anzeige von Linien, Farben usw. zu verwalten. Sie können jedoch auch Newt in Red Hat Anaconda als gemeinsam genutzte Bibliothek sehen, die von Python aufgerufen wird (mit demselben Erscheinungsbild). Entsprechend startete das Kernel-Konfigurationsprogramm als (gekürzte) Kopie des Dialogs und entwickelte sich dann mithilfe einer gemeinsam genutzten Bibliothek (ohne das ursprüngliche lxdialogProgramm) zu Features, ähnlich wie Newt in Python verwendet wird.

Von Bash - Sie können entweder Dialog oder Whiptail für die am häufigsten verwendeten Funktionen verwenden. Jemand hat einen Wrapper für diese (in Perl) geschrieben , damit Skripte diese oder einige andere Skripte einfacher verwenden können. Sie sollten jedoch den Dialog direkt verwenden, da das Perl-Modul im Wesentlichen ein gemeinsamer Nenner ist.

Die Dialogquellen enthalten Beispiele für alle Widgets sowie die meisten Befehlszeilenoptionen:

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.

Weitere Lektüre:

Thomas Dickey
quelle
11

Ich glaube, das Paket, das Sie suchen, ist ncurses .

Wikipedia beschreibt ncurses wie folgt:

ncurses (new curses) ist eine Programmierbibliothek mit einer API, die es dem Programmierer ermöglicht, textbasierte Benutzeroberflächen terminalunabhängig zu schreiben. Es handelt sich um ein Toolkit zur Entwicklung einer "GUI-ähnlichen" Anwendungssoftware, die unter einem Terminalemulator ausgeführt wird

Es wird beispielsweise häufig im Kernel-Konfigurationstool menuconfig verwendet: Screenshot des Linux-Kernel-Tools menuconfig

Da Sie bash verwenden, können Sie Bash Simple Curses verwenden (wie von Runium im Kommentar unten erwähnt).

Thawn
quelle
11
ncursesist eine C-Bibliothek. (Wenn ich es richtig verstehe) OP möchte eine Scripting- Umgebung (für Bash). menuconfigwird in C geschrieben. Als Alternative zu dialog, wie in der anderen Antwort, könnten Sie vielleicht Bash Simple Curses erwähnen, das in bash (unter Berufung auf tput) geschrieben ist.
Runium
@Runium: Danke für die Klarstellung und den Link zu Bash Simple Curses.
Thawn
2
Trotzdem war es nützlich zu erwähnen, dass dies ncursesdie Grundlage ist und eine allgemeinere Version der Frage beantwortet ... wie die im Titel hier :)
underscore_d
-1

Lebensfreude

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-Dialogeintrag mit Optionen

password=$(zenity --password)

Zenity - Passwort

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

zenity - Dateiauswahl

zenity --help

zenity --hilfe resultat

zenity --help-general 

zenity - allgemeines Ergebnis

zenity --help-entry

Zenity --Hilfe-Eintrag Ergebnis

andere grafische Benutzeroberflächen (GUI)

dialog

Dialog

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

stoppt die weitere Ausführung des Skripts, bricht es jedoch ab. die Zeile: echo $? , Wird nie passieren

Feuer im Himmel
quelle