Jak utworzyć GUI oparte na terminalu?

50

Chcę utworzyć środowisko oparte na terminalu, w którym można dostosować mój skrypt Bash . Chcę, aby wyglądało to tak:

Instalacja Debiana

tempforFind Me In The Woods
źródło
4
Spójrz na dialogto, co wydaje się używać.
DopeGhoti
Myślę, że GUI oparte na terminalach to TUI (który różni się od CLI).
UniversallyUniqueID
„tui” to pojęcie RH IIRC. whiptail> dialogtakże
Bratchley
@Bratchley: GDB używa również tuiw trybie podzielonego okna (na przykład pokazuje rejestry, źródło i polecenia layout regoraz tui reg vecwyświetla rejestry wektorowe w oknie reg (w sposób nieelastyczny, aby ta część nie była naprawdę przydatna: /) , IDK, jeśli Redhat napisał łatkę, która dodała tę funkcję, a nawet ile ona ma lat
Peter Cordes

Odpowiedzi:

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

wprowadź opis zdjęcia tutaj

Odpowiedź użytkownika jest przechowywana w kodzie wyjścia, więc można ją wydrukować jak zwykle: echo $?(zwróć uwagę, że 0oznacza to „tak” i 1w świecie powłoki jest „nie”).


Odnośnie innych pytań z sekcji komentarzy:

  • aby wstawić do okna dialogowego dane wyjściowe z niektórych poleceń, wystarczy użyć mechanizmu zastępowania poleceń $(), np .:

     dialog --backtitle "$(echo abc)" --title "$(cat file)" ...
    
  • aby dać użytkownikowi wiele możliwości, możesz użyć --menuopcji zamiast--yesno

  • aby zapisać dane wyjściowe użytkownika w zmiennej, należy użyć --stdoutopcji lub zmienić deskryptor wyjściowy za pomocą --output-fdlub ręcznie, np .:

    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"
    

    Ta sztuczka jest potrzebna, ponieważ dialogdomyślnie wypisuje na stderr, a nie na standardowe wyjście.

I jak zawsze man dialogjest twoim przyjacielem.

jimmij
źródło
to piękne „Bla bla bla ...”, ale jak uchwycić wynik?
tempforFind Me In The Woods
1
@tempforFindMeInTheWoods jeśli przez dane wyjściowe rozumiesz kod wyjścia, to tak jak zwykle: jest przechowywany w ?zmiennej, spróbuj echo $?.
jimmij
1
@tempforFindMeInTheWoods Jeśli chcesz przedstawić użytkownikowi dane wyjściowe polecenia parted -lza pomocą okna dialogowego, prawdopodobnie --menulepszym wyborem jest opcja -yesno. W takim przypadku musiałbyś zagrać trochę z deskryptorami, aby zapisać dane wyjściowe w zmiennej, na przykład: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
Lub możesz skorzystać z tej --stdoutopcji.
Thomas Dickey
2
Wszystkie opcje dialogowe są wyjaśnione w instrukcji:man dialog
Ferrybig
34

Zrzut ekranu w pytaniu wygląda jak whiptail (funkcjonalnie zredukowany program imitujący okno dialogowe , używający raczej traszki niż ncurses ). Sposób renderowania tytułu i przycisków jest wbudowany w każdy program, dzięki czemu wyglądają inaczej.

Oto skrypt, który powiela oryginalny zrzut ekranu, zarówno dla whiptail, jak i dialogu:

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

i dla porównania zrzut ekranu z whiptail:

zrzut ekranu z whiptail

i z dialogiem:

zrzut ekranu z oknem dialogowym

Oprócz odmiennego wyglądu tytułu i przycisków, okno dialogowe domyślnie używa różnych kolorów (choć można to konfigurować - patrz zrzuty ekranu ) i używa mniej linii na ekranie.

okna dialogowe (i whiptail) używają bibliotek do zarządzania wyświetlaniem linii, kolorów itp. Ale możesz także zobaczyć traszkę używaną w programie anakondy Red Hat jako bibliotekę współdzieloną o nazwie z python (o takim samym wyglądzie). W tym samym wierszu program konfiguracyjny jądra uruchomił się jako (skrócona) kopia okna dialogowego, a następnie przekształcił się w funkcje przy użyciu wspólnej biblioteki (bez oryginalnego lxdialogprogramu), podobnie jak traszka jest używana z pythona.

From bash - możesz użyć okna dialogowego lub whiptail dla najczęściej używanych funkcji. Ktoś napisał opakowanie dla tych (w perlu), aby umożliwić skryptom łatwiejsze korzystanie z tych lub kilku innych, ale lepiej jest używać okna dialogowego bezpośrednio, ponieważ moduł perla jest zasadniczo wspólnym mianownikiem.

Źródła okien dialogowych zawierają przykłady wszystkich widżetów wraz z większością opcji wiersza poleceń:

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.

Dalsza lektura:

Thomas Dickey
źródło
11

Wierzę, że pakiet, którego szukasz, to ncurses .

Wikipedia opisuje ncurses następująco:

ncurses (nowe klątwy) to biblioteka programistyczna zapewniająca interfejs API, który pozwala programiście pisać tekstowe interfejsy użytkownika w sposób niezależny od terminali. Jest to zestaw narzędzi do opracowywania oprogramowania typu „GUI” działającego pod emulatorem terminala

Jest szeroko stosowany na przykład w narzędziu konfiguracyjnym jądra menuconfig: Zrzut ekranu narzędzia menuconfig jądra Linux

Ponieważ używasz bash, możesz użyć Bash Simple Curses (jak wspomniano w Runium w komentarzu poniżej).

Odwilż
źródło
11
ncursesjest biblioteką C. (Jeśli dobrze rozumiem) OP chce środowiska skryptowego (dla bash). menuconfigjest napisane w C. Jako alternatywę dla dialog, jak na inną odpowiedź, być może mógłbyś wspomnieć Bash Simple Curses, które jest napisane bash (poleganie na tput).
Runium
@Runium: Dziękujemy za wyjaśnienie i link do Bash Simple Curses.
Odwilż
2
warto jednak wspomnieć, że ncursesjest to podstawa, i odpowiada na bardziej ogólną wersję pytania ... taką jak ta tutaj w tytule :)
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)

pozycja okna dialogowego zenity z opcjami

password=$(zenity --password)

zenity - hasło

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

zenity - wybór pliku

zenity --help

zenity - wynik pomocy

zenity --help-general 

zenity - pomoc ogólny wynik

zenity --help-entry

zenity - wynik wpisu pomocy

inne graficzne interfejsy użytkownika (GUI)

dialog

dialog

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

zatrzymuje dalsze wykonywanie skryptu, psuje go. linia: echo $? , nigdy się nie zdarzy

Ogień na niebie
źródło