Comment créer une interface graphique basée sur un terminal?

50

Je cherche à créer un environnement basé sur un terminal dans lequel adapter mon script Bash . Je veux que ça ressemble à ça:

Installation de Debian

tempforTrouvez-moi dans les bois
la source
4
Regardez dans dialog, qui est ce que cela semble utiliser.
DopeGhoti
Je pense qu'une interface graphique basée sur un terminal est une TUI (qui est différente de la CLI).
UniversallyUniqueID
"tui" est un terme RH IIRC. whiptail> dialogaussi
Bratchley
@Bratchley: GDB utilise également tuipour son mode fenêtre divisée (affichage des registres, source et commandes avec layout regpar exemple, et tui reg vecpour afficher les registres de vecteurs dans la fenêtre reg (de manière non flexible, afin que cette partie ne soit pas vraiment utile: /) . IDK si Redhat a écrit le patch qui a ajouté cette fonctionnalité, ou même quel âge il est.
Peter Cordes

Réponses:

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

entrez la description de l'image ici

La réponse de l'utilisateur est stockée dans le code de sortie, elle peut donc être imprimée comme d'habitude: echo $?(notez que cela 0signifie "oui" et 1est "non" dans le monde du shell).


Concernant d’autres questions de la section commentaire:

  • pour mettre dans la boîte de dialogue le résultat d'une commande, utilisez simplement le mécanisme de substitution de commande $(), par exemple:

     dialog --backtitle "$(echo abc)" --title "$(cat file)" ...
    
  • pour donner à l'utilisateur plusieurs choix, vous pouvez utiliser l' --menuoption au lieu de--yesno

  • pour stocker la sortie du choix de l'utilisateur dans la variable, il faut utiliser l' --stdoutoption ou modifier le descripteur de sortie via --output-fdou manuellement, par exemple:

    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"
    

    Cette astuce est nécessaire car, dialogpar défaut, les sorties sur stderr, pas stdout.

Et comme toujours, man dialogc'est ton ami.

Jimmij
la source
c'est beau "Bla bla bla ..." mais comment capturez-vous la sortie?
tempforTrouvez-moi dans les bois
1
@tempforFindMeInTheWoods si par sortie vous entendez le code de sortie, alors comme d'habitude: il est stocké dans une ?variable, essayez echo $?.
Jimmij
1
@tempforFindMeInTheWoods Si vous souhaitez présenter la sortie de la commande parted -là l'utilisateur via une boîte de dialogue, l'option --menuest probablement préférable -yesno. Dans ce cas, vous devrez jouer un peu avec les descripteurs pour stocker le résultat dans la variable, par exemple: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
Ou, vous pouvez utiliser l' --stdoutoption.
Thomas Dickey
2
Toutes les options de la boîte de dialogue sont expliquées dans le manuel:man dialog
Ferrybig
34

La capture d’écran de la question ressemble à whiptail (programme qui imite les dialogues avec un nombre réduit de fonctions , en utilisant newt plutôt que ncurses ). La manière dont le titre et les boutons sont rendus est intégrée à chaque programme, ce qui leur donne un aspect différent.

Voici un script qui duplique la capture d’écran d’origine, que ce soit pour whiptail ou dialog:

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

et pour comparaison, capture d'écran avec whiptail:

capture d'écran avec whiptail

et avec dialogue:

capture d'écran avec dialogue

Outre l'apparence différente du titre et des boutons, la boîte de dialogue utilise des couleurs différentes par défaut (bien que cela soit configurable - voir les captures d'écran ) et utilise moins de lignes à l'écran.

dialog (et whiptail) utilisent des bibliothèques pour gérer l’affichage des lignes, des couleurs, etc. Mais vous pouvez également voir que newt est utilisé dans le programme Red Hat anaconda en tant que bibliothèque partagée appelée à partir de python (avec la même apparence). Dans le même ordre d'idées, le programme de configuration du noyau a commencé comme une copie (tronquée) de la boîte de dialogue, puis a évolué vers des fonctionnalités utilisant une bibliothèque partagée (sans le lxdialogprogramme d' origine ), un peu à la manière dont newt est utilisé depuis python.

De bash - vous pouvez utiliser soit dialog ou whiptail pour les fonctionnalités les plus couramment utilisées. Quelqu'un a écrit un wrapper pour que ceux-ci (en Perl) autorisent les scripts à utiliser plus facilement ceux-ci ou quelques autres, mais il vaut mieux utiliser dialog directement puisque le module perl a essentiellement un dénominateur commun.

Les sources de dialogue incluent des exemples de tous les widgets, ainsi que la plupart des options de ligne de commande:

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.

Lectures complémentaires:

Thomas Dickey
la source
11

Je crois que le paquet que vous recherchez est ncurses .

Wikipedia décrit ncurses comme suit:

ncurses (new curses) est une bibliothèque de programmation fournissant une API qui permet au programmeur d'écrire des interfaces utilisateur textuelles indépendamment du terminal. Il s’agit d’une boîte à outils permettant de développer un logiciel d’application de type "interface graphique" fonctionnant sous un émulateur de terminal.

Il est largement utilisé, par exemple, dans l'outil de configuration du noyau menuconfig: Capture d'écran de l'outil menuconfig du noyau Linux

Puisque vous utilisez bash, vous pouvez utiliser Bash Simple Curses (comme mentionné par Runium dans le commentaire ci-dessous).

Décongelé
la source
11
ncursesest une C-bibliothèque. (Si je comprends bien) OP veut un environnement de script (pour bash). menuconfigest écrit en C. Au lieu de dialog, comme indiqué dans une autre réponse, vous pourriez peut-être mentionner Bash Simple Curses qui est écrit en bash (compter tput).
Runium
@Runium: Merci pour la clarification et le lien vers Bash Simple Curses.
Décongelé
2
Pourtant, il était utile de mentionner que ncursesc'est la base de ceci, et cela répond à une version plus générale de la question ... comme celle du titre ici :)
underscore_d
-1

zenity

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)

entrée de dialogue zenity avec options

password=$(zenity --password)

zenity --password

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

zenity --file-selection

zenity --help

zenity - résultat utile

zenity --help-general 

zenity --help-resultat général

zenity --help-entry

zenity --help-entry result

autres interfaces utilisateur graphiques (GUI)

dialog

dialogue

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

arrête l'exécution ultérieure du script, le casse. la ligne: echo $? , ne se produira jamais

Feu dans le ciel
la source