Come si crea una GUI basata su terminale?


50

Sto cercando di creare un ambiente basato su terminali in cui adattare il mio script Bash . Voglio che assomigli a questo:

Installazione di Debian


4
Guarda dialog, che è ciò che sembra usare.
DopeGhoti,


Penso che una GUI basata su terminali sia una TUI (che è diversa dalla CLI).
UniversallyUniqueID,

"tui" è un termine RH IIRC. whiptail> dialoganche
Bratchley

@Bratchley: GDB usa anche tuiper la sua modalità a finestra divisa (mostrando registri, sorgente e comandi con layout regper esempio, e tui reg vecper mostrare registri vettoriali nella finestra reg (in modo non flessibile, quindi quella parte non è davvero utile: /) IDK se Redhat ha scritto la patch che ha aggiunto quella funzione, o anche quanti anni ha
Peter Cordes,

Risposte:


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

inserisci qui la descrizione dell'immagine

La risposta dell'utente è memorizzata nel codice di uscita, quindi può essere stampata come al solito: echo $?(notare che 0significa "sì", ed 1è "no" nel mondo della shell).


Per quanto riguarda altre domande dalla sezione commenti:

  • per inserire nella finestra di dialogo l'output di alcuni comandi basta usare il meccanismo di sostituzione dei comandi $(), ad esempio:

     dialog --backtitle "$(echo abc)" --title "$(cat file)" ...
    
  • per offrire all'utente più scelte, è possibile utilizzare l' --menuopzione anziché--yesno

  • per memorizzare l'output della scelta dell'utente nella variabile è necessario utilizzare l' --stdoutopzione o modificare il descrittore dell'output tramite --output-fdo manualmente, ad esempio:

    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"
    

    Questo trucco è necessario perché dialogper impostazione predefinita restituisce stderr, non stdout.

E come sempre, man dialogè tuo amico.


è bellissimo "Bla bla bla ..." ma come catturi l'output?
tempforTrovami nel bosco

1
@tempforFindMeInTheWoods se per output intendi il codice di uscita, quindi come al solito: è memorizzato all'interno della ?variabile, prova echo $?.
Jimmij,

1
@tempforFindMeInTheWoods Se si desidera presentare l'output del comando parted -lall'utente tramite la finestra di dialogo, probabilmente l'opzione --menuè una scelta migliore anziché -yesno. In tal caso dovresti giocare un po 'con i descrittori per memorizzare l'output nella variabile, ad esempio: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
In alternativa, è possibile utilizzare l' --stdoutopzione.
Thomas Dickey,

2
Tutte le opzioni di dialogo sono spiegate nel manuale:man dialog
Ferrybig

34

Lo screenshot nella domanda sembra una coda di rondine (un programma a funzionalità ridotta che imita il dialogo , usando newt piuttosto che ncurses ). Il modo in cui vengono visualizzati il ​​titolo e i pulsanti è integrato in ciascun programma, rendendoli diversi.

Ecco uno script che duplica lo screenshot originale, sia per la coda che per la finestra di dialogo:

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

e per confronto, screenshot con whiptail:

screenshot con coda di cavallo

e con la finestra di dialogo:

screenshot con finestra di dialogo

Oltre al diverso aspetto del titolo e dei pulsanti, la finestra di dialogo utilizza colori diversi per impostazione predefinita (sebbene sia configurabile, vedere schermate ) e utilizza meno linee sullo schermo.

dialog (e whiptail) usano le librerie per gestire la visualizzazione di linee, colori, ecc. Ma potresti anche vedere newt usato nel programma anaconda di Red Hat come una libreria condivisa chiamata da Python (con lo stesso aspetto). Sulla stessa linea, il programma di configurazione del kernel è iniziato come una copia (ridotta) della finestra di dialogo, quindi si è evoluto in funzionalità usando una libreria condivisa (senza il lxdialogprogramma originale ) proprio come il modo in cui newt viene usato da Python.

Da bash - puoi usare la finestra di dialogo o la coda per le funzioni più comunemente usate. Qualcuno ha scritto un wrapper per quelli (in perl) per consentire agli script di usare più facilmente quelli o pochi altri, ma è meglio usare direttamente i dialoghi poiché il modulo perl è essenzialmente un comune denominatore.

Le fonti della finestra di dialogo includono esempi di tutti i widget insieme alla maggior parte delle opzioni della riga di comando:

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.

Ulteriori letture:


11

Credo che il pacchetto che stai cercando sia ncurses .

Wikipedia descrive ncurses come segue:

ncurses (new curses) è una libreria di programmazione che fornisce un'API che consente al programmatore di scrivere interfacce utente basate su testo in modo indipendente dal terminale. È un toolkit per lo sviluppo di software applicativo "simile alla GUI" che gira sotto un emulatore di terminale

È ampiamente usato, ad esempio, nello strumento di configurazione del kernel menuconfig: Schermata dello strumento menuconfig del kernel Linux

Dato che stai usando bash, puoi usare Bash Simple Curses (come menzionato da Runium nel commento qui sotto).


11
ncursesè una libreria C. (Se ho capito bene) OP vuole un ambiente di scripting (per bash). menuconfigè scritto in C. In alternativa dialog, come per altre risposte, potresti forse menzionare Bash Simple Curses che è scritto in bash (basandosi su tput).
Runium,

@Runium: grazie per il chiarimento e il link a Bash Simple Curses.
Thawn,

2
tuttavia, è stato utile menzionare che ncursesè la base di questo, e risponde a una versione più generale della domanda ... come quella nel titolo qui :)
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)

voce della finestra di dialogo zenity con opzioni

password=$(zenity --password)

zenity: password

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

zenity: selezione dei file

zenity --help

zenity: risultato di aiuto

zenity --help-general 

Zenit: risultato generale di aiuto

zenity --help-entry

zenity - risultato dell'aiuto

altre interfacce utente grafiche (gui)

dialog

dialogo

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

interrompe ulteriormente l'esecuzione dello script, lo interrompe. la linea: echo $? , non accadrà mai

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.