2009-10-13 11 views
6

Ich habe ein großartiges kleines Programm gefunden, mit dem ich benutzerfreundliche GUI's zu meinen Bash-Skripten hinzufügen kann;BASH-Skripte: Whiptail-Datei wählen

whiptail

jedoch die whiptail man page nicht alles, was nützlich ist und keine Beispiele nicht zur Verfügung stellt. Einige Google-Suche nach dem Handeln verstehe ich, wie man ein einfaches Ja erstellen/nein Menü whiptail:

#! /bin/bash 
# http://archives.seul.org/seul/project/Feb-1998/msg00069.html 
if (whiptail --title "PPP Configuration" --backtitle "Welcome to SEUL" --yesno " 
Do you want to configure your PPP connection?" 10 40) 
then 
     echo -e "\nWell, you better get busy!\n" 
elif (whiptail --title "PPP Configuration" --backtitle "Welcome to 
SEUL" --yesno "   Are you sure?" 7 40) 
     then 
       echo -e "\nGood, because I can't do that yet!\n" 
     else 
       echo -e "\nToo bad, I can't do that yet\n" 
fi 

Aber was würde ich wirklich eine Datei wählen Sie das Menü mit whiptail bauen möchte einige alte Code, den ich in ein paar haben zu ersetzen verschiedene Backup/Restore-bash-Skripte ich habe:

#!/bin/bash 
#This script allows you to select a file ending in the .tgz extension (in the current directory) 
echo "Please Select the RESTORE FILE you would like to restore: " 
    select RESTOREFILE in *.tgz; do 
    break #Nothing 
    done 
echo "The Restore File you selected was: ${RESTOREFILE}" 

ich nehme an, das über die ‚--menu‘ Option von whiptail getan werden muss, aber ich bin nicht sicher, wie man das macht? Irgendwelche Zeiger? Oder können Sie mich in Richtung einiger Whiptail Beispiele zeigen?

+0

Ich habe eine kleine Änderung an meiner Antwort vorgenommen (die oktale Umrechnungsformel). –

Antwort

8

Erstellen ein Array von Dateinamen und Menüauswahl tags:

i=0 
s=65 # decimal ASCII "A" 
for f in *.tgz 
do 
    # convert to octal then ASCII character for selection tag 
    files[i]=$(echo -en "\0$(($s/64 * 100 + $s % 64/8 * 10 + $s % 8))") 
    files[i+1]="$f" # save file name 
    ((i+=2)) 
    ((s++)) 
done 

Verfahren wie dies funktionieren wird, auch wenn es Dateinamen mit Leerzeichen. Wenn die Anzahl der Dateien groß ist, müssen Sie möglicherweise eine andere Tag-Strategie entwickeln.

Mit alphabetischen Zeichen für die Tags können Sie einen Buchstaben drücken, um zu dem Element zu springen. Numerische Tags scheinen das nicht zu tun. Wenn Sie dieses Verhalten nicht benötigen, können Sie eine gewisse Komplexität eliminieren.

Rufen Sie das Menü:

whiptail --backtitle "Welcome to SEUL" --title "Restore Files" \ 
    --menu "Please select the file to restore" 14 40 6 "${files[@]}" 

Wenn der Exit-Code 255 ist, wurde der Dialog abgebrochen.

if [[ $? == 255 ]] 
then 
    do cancel stuff 
fi 

Um die Auswahl in einer Variablen zu fangen, diese Struktur verwenden (für "whiptail-Befehl" Ihr whiptail Befehl ersetzen):

result=$(whiptail-command 2>&1 >/dev/tty) 

Oder

result=$(whiptail-command 3>&2 2>&1 1>&3-) 

Die Variable $result wird enthält einen Buchstaben des Alphabets, der einer Datei im Array entspricht. Unglücklicherweise unterstützt Bash vor Version 4 keine assoziativen Arrays. Sie können den Index in das Array der Datei aus dem Brief wie folgt (man beachte die „extra“ Apostroph) berechnen:

((index = 2 * ($(printf "%d" "'$result") - 65) + 1)) 

Beispiel:

Welcome to SEUL 
       ┌──────────┤ Restore Files ├───────────┐ 
       │ Please select the file to restore │ 
       │          │ 
       │   A one.tgz  ↑   │ 
       │   B two.tgz  ▮   │ 
       │   C three.tgz ▒   │ 
       │   D another.tgz ▒   │ 
       │   E more.tgz  ▒   │ 
       │   F sp ac es.tgz ↓   │ 
       │          │ 
       │          │ 
       │  <Ok>   <Cancel>  │ 
       │          │ 
       └──────────────────────────────────────┘ 
+0

Bitte beachten Sie: Ich habe meine Antwort bearbeitet, um die vorherige Oktalumrechnungsformel zu ersetzen, die ( fast) völlig falsch war. –

+0

Für temporäre Dateien können Sie mktemp verwenden. Zum Beispiel mytempfile=$(mktemp) ; echo "Hello world">$mytempfile; echo Contents of ${mytempfile}: $(cat $mytempfile) ; rm -f $mytempfile jbatista

+0

@jbatista: Das stimmt, aber wie ist es anwendbar? Temporäre Dateien werden hier nicht erwähnt. –

3

Whiptail ist eine leichte Reimplementierung der beliebtesten Funktionen von dialog, mit der Newt library. Ich habe eine kurze Überprüfung durchgeführt und viele Funktionen in Whiptail scheinen sich wie ihre Gesprächspartner im Dialog zu verhalten. Also sollte ein Dialog-Tutorial Ihnen den Anfang machen. Sie können eine here finden, aber Google ist natürlich Ihr Freund. Auf der anderen Seite enthält die extended example wahrscheinlich eine Menge Inspiration für Ihr Problem.

0

Ich habe versucht, folgende, die gearbeitet:

whiptail --title "PPP Config" --backtitle "Welcome to SEUL" --menu YourTitle 20 80 10 `for x in $(ls -1 *.tgz); do echo $x "-"; done` 

Sie könnte dies in eine als auch mehrere Liner ändern, ich habe hinzugefügt für leere Liste überprüft:

MYLIST=`for x in $(ls -1 *.tgz); do echo $x "-"; done` 
WC=`echo $MYLIST | wc -l` 

if [[WC -ne 0]]; then 
    whiptail --title "PPP Config" --backtitle "Welcome to SEUL" --menu YourTitle 20 80 10 $MYLIST 
fi 

Sie brauchen um die Zahlen anzupassen, um eine reine Schnittstelle zu erhalten. Und Sie können die "-" durch etwas anderes ersetzen, wenn Sie möchten. Wenn Sie dies nicht tun, sehen Sie 2 Einträge pro Zeile.

Übrigens: Der ausgewählte Eintrag wird auf stderr gedruckt.

Das könnte etwas mehr Verbesserung benötigen, aber für eine Grundidee denke ich, es ist genug.

0

Dies scheint eine der oben zu sein Ergebnisse, wenn Sie nach whiptail suchen, und keine der vorherigen Ergebnisse für mich gearbeitet. Dies ist, was ich aufgewickelt mit:

#! /bin/bash 
shopt -s nullglob 
dir=`pwd` 
cd /path/to/files 
arr=(*.tgz) 
for ((i=0; i<${#arr[@]}; i++)); do j=$((2*$i+2)); a[j]="${arr[$i]}"; a[j+1]=""; done 
a[0]="" 
# Next line has extra spaces at right to try to center it: 
a[1]="Please make a selection from the files below              " 
result=$(whiptail --ok-button "OK button text" --cancel-button "Cancel Button Text" --title "Title Text" --backtitle "Text at upper left corner of page" --menu "Menu Text (not used??)" 30 160 24 "${a[@]}" 2>&1 >/dev/tty) 
if [[ $? = 0 ]] 
then 
# ge 5 in next line should be length of file extension including . character, plus 1 
    [ ${#result} -ge 5 ] && outfile="/path/to/files/$result" || echo "Selection not made" 
fi 
cd "$dir" 

$ Ergebnis wird leer sein, wenn keine gültige Auswahl getroffen wurde. Ich habe eine Dummy-Auswahl oben in der Liste hinzugefügt, die als Ergebnis eine leere Zeichenfolge zurückgibt, sodass Sie nicht versehentlich die falsche Datei auswählen, indem Sie versehentlich Enter drücken, nachdem das Menü angezeigt wird. Wenn Sie das nicht wollen, dann entfernen Sie in der "for" -Zeile die +2 in "do j = $ ((2 * $ i + 2))" und auch die folgenden zwei Zeilen, die a [0] und a setzen [1] explizit. Das verwirrende an Whiptail ist, dass beim Lesen von einem Array in einer Situation wie dieser zwei Datenelemente pro Zeile erwartet werden, die beide angezeigt werden, wobei das erste das Ergebnis ist, das zurückgegeben werden soll, wenn die Zeile erwartet wird (was In manchen Situationen könnte es sich um einen Buchstaben oder eine Zahl handeln, und der zweite wäre ein beliebiger Beschreibungstext. Deshalb verwende ich für die erste Zeile eine [0], um eine leere Zeichenfolge als Ergebnis und eine [1] als beschreibenden Text zu geben, aber von dort an enthält das erste Element in dem Paar den Dateinamen (was ich tatsächlich bin will zurückgegeben werden) und die zweite ist eine leere Zeichenfolge, da ich keinen anderen Text als den Dateinamen in diesen Zeilen anzeigen möchte.

Auch ein vorheriger Beitrag sagte whiptail gab einen Fehlercode von 255 zurück, wenn die Abbrechen-Taste gedrückt wurde, aber das war nicht der Fall für die Version, die ich habe - es gibt 1 zurück. Also ich nur für einen Fehlercode von 0 und Wenn es der Fall ist, nehme ich an, dass es ein gültiger Eintrag sein kann, dann prüfe ich nach einer gültigen Zeichenfolgenlänge (mehr als nur die Anzahl von Zeichen in der Dateiendung, einschließlich des Zeichens.), um sicher zu sein.