eingaberoutine in bash - space mit read

M

manfred

Jungspund
Hallo Leute,

erst mal ein Lob. Auf meiner Lösungssuche bin ich hier über euer Forum gestolpert, was Ihr hier für Tipps gebt, ist ja richtig Profihaft, - dickes Lob an euch -

Als "Rübergucker" aus der Windowswelt versuche ich nun, "Xubuntu feisty fawn" ein paar spezielle Funktionen beizubringen, ohne Xubuntu durch zusätzliche Pakete aufblähen zu müssen = mit der Shell, genauer Xterm

Und für diese Helferleins versuche ich grad, eine Eingaberoutine zu erstellen.
Eigentlich komm ich gut voran (kann Sondertasten abfangen und auswerten, Sonderzeichen umsetzen) aber bei einem Problem fehlen mir Ideen bzw. Hintergrundwissen.

Der "read"-Befehl der Shell unterschlägt mir die Leertasten.

Mit folgendem (aufs wesentliche gekürtzten) Script läßt sich das demonstrieren:

Code:
echo ===============================================================================
echo mk_abfrage.script                Eastler                27.Aug.2007/27.Aug.2007
echo -------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------------------------------------------------------
FragEinfachTasteAb () {
   ruckgabe="keine"                      # dummystartparameter in $ruckgabe, daß die whileschleife erst mal läuft
   unset zeichen                         # da diese Routine mehrfach aufgerufen wird, für den Start $zeichen leeren
   while [ "$ruckgabe" = "keine" ]; do
#         zeichen=""
         read -n1 -t1 -s zeichen            # lese eine Sekunde lang (-t1) genau 1 Zeichen (-n1) von der Tastatur ohne Anzeige (-s)
         zeitflag="$?"                   # Rückgabefehlerwert von read in Var speichern (0=es war eine Eingabe,  1=Zeit abgelaufen)
               case "$zeichen" in
                  " ") ruckgabe="_" ;;            # fehlschlagender Versuch die Eingabe der Leertaste abzufragen
                  $'\x20') zeichen="_" ;;         # ebenfalls fehlschlagender Versuch die Eingabe der Leertaste abzufragen
                  $'\x1b') zeichen="st:" ; echo -n "|" ; ruckgabe="Sondertaste" ;;         # byte war chr$(27)
                  *) ruckgabe=$zeichen ;;         # bei allen anderen Tasten 1:1 die Eingabe per $ruckgabe zurückgeben
               esac
         # echo "Länge der Eingabe: ${#zeichen}"  # damit getestet, wie land $zeichen ist, wenn fuer read ein Space gedrückt wird. IMMER NULL :-(
      done
      return #$ruckgabe
}
#===============================================================================
# Hauptroutine
#===============================================================================
   while [ "$ruckgabe" != "Sondertaste" ]; do
      FragEinfachTasteAb
      echo -n $ruckgabe
      eingabe=$eingabe$ruckgabe
   done
echo 
echo -------------------------------------------------------------------------------
echo "Ihre Eingaben waren: $eingabe"
echo ===============================================================================
kurz beschreibend:
das Unterprogramm "FragEinfachTasteAb" holt mittels read immer ein Byte von der Tastatur und gibt dieses über die variable $ruckgabe an das Hauptprogramm zurück.
Das Hauptprogramm hängt dieses Byte an eine Variable dran ($eingabe) und läßt sich von "FragEinfachTasteAb" die nächsten Bytes geben, bis die Escape-Taste gedrückt wurde.

das Problem:
read gibt beim Drücken der Spacetaste den chr$(32) nicht in die Variable $Zeichen, sondern läßt diese Variable einfach leer (mit Länge null).

Würde ich jetzt "read" nicht mit Parameter -n1 dazu überreden, nur ein Zeichen (kein Return nötig) einzulesen, dann wären die gedrückten spaces mit in der Variable drin, aber bei EinCharEingaben unterdrückt read diese.

Kennt jemand einen Trick, wie man doch an diese Spaces rankommt?

Besten Dank für euer grübeln im voraus

Manfred
 
hihi, scheint auch für euch ne harte Nuß zu sein :-)

Da es MICH naturgemäß am meißten interessiert, war ich dann der eifrigste
Lösungsucher und hab am schnellsten die Antwort gefunden - grins.

Das Problem der verwschwindenden Spaces liegt an der "Intelligenz" von dem
Befehl "read".
Read versucht, führende Wort- und Zeilentrennzeichen zu eliminieren, sodaß
bei z.B. einlesen von Dateizeilen per read aus:
Code:
    # Dateiinhalt beispielhaft:
    das ist normal
          eine eingerückte Zeile
    normal wieder weiter in der Datei
per read zeile ; echo $zeile folgende Anzeige enstehen würde:
Code:
    # Ausgabe per read zeile ; echo $zeile:
    das ist normal
    eine eingerückte Zeile
    normal wieder weiter in der Datei
soweit zu dem Hintergrund, warum read sowas macht.
jetzt die Lösung, wie man in meinem Fall read dieses Feature
abgwöhnen kann:

Read eliminiert wie schon gesagt führende Wort- und Zeilentrennzeichen.
Dabei schaut read in der (globalen ?) Variable IFS nach, welche Zeichen
als Wort- und Zeilentrenner gelten.
Somit braucht nur der Inhalt von IFS geändert werden.
Folgendes Beispiel verdeutlicht dies und sorgt auch noch dafür, daß
nach dem Ausführen des read-Befehls IFS wieder seine ursprünglichen
Werte erhält:
Code:
#! /bin/bash
#
echo ===============================================================================
echo mk_abfrage.script                Eastler                27.Aug.2007/27.Aug.2007
echo -------------------------------------------------------------------------------
# --------------------------------------------------------------------------------------------------------------------------------------------------
FragEinfachTasteAb () {
   # der Shell-Befehl "read" versucht intelligent zu sein. wenn Eingaben reinkommen,
   # werden führende Wort/Zeilentrennzeichen entfernt - und Space ist halt auch ein
   # Wort-Trenn-Zeichen. Wir wollen hier aber das Space als "normale" Eingabetaste
   # haben. Somit müssen wir "read" dies irgendwie erklären.
   # "read" schaut in der Variablen $IFS nach, was Wort- und Zeilen-trennzeichen sind.
   # Entsprechend brauchen wir also nir den Inhalt von $IFS sinnvoll ändern.
   # Sinnvoll für uns ist, die Zeilenschaltung als Trennzeichen nimmt, alles andere
   # kann weg. 
   # Da noch andere Commands nach IFS$ schauen, müssen wir auch dafür Sorge tragen,
   # daß nach unserem "read" sofort der ursprüngliche Inhalt von IFS wieder hergestellt
   # wird.
   ruckgabe="keine"                      # dummystartparameter in $ruckgabe, daß die whileschleife erst mal läuft
   while [ "$ruckgabe" = "keine" ]; do
         zeichen=""
         org_ifs=$IFS   # (Original-) Inhalt von IFS in $org_ifs sichern
         IFS="
"        # einfach eine Zeilenschaltung (die aus dem Zeilenwechsel des scriptes zwischen den Apostrophen der vorigen und dieser Zeile) in IFS setzten
         # damit read die Zeilenschaltung als Zeichentrenner noch annimt
         read -n1 -t1 -s zeichen            # lese eine Sekunde lang (-t1) genau 1 Zeichen (-n1) von der Tastatur ohne Anzeige (-s)
         IFS=$org_ifs                       # Den originalen Inhalt von IFS wieder herstellen
         zeitflag="$?"                      # Rückgabefehlerwert von read in Var speichern (0=es war eine Eingabe,  1=Zeit abgelaufen)
               case "$zeichen" in
                  " ") ruckgabe="_" ; umlautflag="" ;;            # fehlschlagender Versuch die Eingabe der Leertaste abzufragen
                  $'\x1b') zeichen="st:" ; echo -n "|Sondertaste|" ; ruckgabe="Sondertaste" ;;         # byte war chr$(27)
                  $'\xc3') umlautflag="gestartet" ;;  #Umlaute kommen mit 2 Zeichen rein, das erste ist immer \xc3, das zweite differenziert dann
                  $'\x96') if [ umlautflag="gestartet" ] ; then ruckgabe="Oe" ; umlautflag="" ; fi ;;
                  $'\x9C') if [ umlautflag="gestartet" ] ; then ruckgabe="Ue" ; umlautflag="" ; fi ;;
                  $'\x84') if [ umlautflag="gestartet" ] ; then ruckgabe="Ae" ; umlautflag="" ; fi ;;
                  $'\xB6') if [ umlautflag="gestartet" ] ; then ruckgabe="oe" ; umlautflag="" ; fi ;;
                  $'\xbc') if [ umlautflag="gestartet" ] ; then ruckgabe="ue" ; umlautflag="" ; fi ;;
                  $'\xa4') if [ umlautflag="gestartet" ] ; then ruckgabe="ae" ; umlautflag="" ; fi ;;
                  $'\x9f') if [ umlautflag="gestartet" ] ; then ruckgabe="ss" ; umlautflag="" ; fi ;;
                  [$'\x30'-$'\x39'])  ruckgabe=$zeichen ; umlautflag=""  ;;   # alle Zahlen kommen hier an
                  $'\x5a')  ruckgabe=$zeichen ; umlautflag=""  ;;           # grosses Z
                  [$'\x61'-$'\x7a'])  ruckgabe=$zeichen ; umlautflag=""  ;; #alle  kleinen buchstaben und die Grossen bis Y kommen hiermit an
                  "") if [ "$zeitflag" == 0 ] ; then ruckgabe="" ; fi ;;         #read Zeit war nicht abgelaufen = returntaste
               esac
      done
      return #$ruckgabe
}
#===============================================================================
# Hauptroutine
#===============================================================================
   echo "Eingaberoutine mit der Subroutine FragEinfachTasteAb"
   echo "testen Sie LEERTASTE und die Zeichen öäüÖÄÜ und ß ;-)"
   echo "ausgefallene Sonderzeichen werden gar nicht erst angenommen."
   echo
   echo "mit der ESCAPE-Taste beenden Sie diese Eingabe"
   echo
   while [ "$ruckgabe" != "Sondertaste" ]; do
      FragEinfachTasteAb
      echo -n $ruckgabe
      eingabe=$eingabe$ruckgabe
   done
echo 
echo -------------------------------------------------------------------------------
echo "Ihre Eingaben waren: $eingabe"
echo ===============================================================================

Bei Neugier Speichern Sie dieses Script, ändern den Modus auf "ausführbar"
und starten es in der Shell.
Sie können dann in eine Zeile lostippen, "Spaces" werden zu "_",
Umlaute werden in normale Zeichen gewandelt (z.B.: ä wird zu ae),
das scharfe ß wird zu ss.
Mit der Escape-Taste beenden Sie das Script, wobei noch mal eben der
Variableninhalt, der aus Ihrer Eingabe erstellt wurde, angezeigt wird.

In der Hoffnung, daß dies alles jemanden hilft


bis bald, euer Manfred
 
hihi, scheint auch für euch ne harte Nuß zu sein :-)
Nö, nicht wirklich. ;)
Wir sind zwar oft und gern bereit zu antworten, aber bieten nicht 24h Support.
Aber so manch User kommt - nachdem er die Frage richtig formuliert hat - selbst auf die Lösung. ;)
Das Problem der verwschwindenden Spaces liegt an der "Intelligenz" von dem
Befehl "read".
Read versucht, führende Wort- und Zeilentrennzeichen zu eliminieren, sodaß
Nein, read versucht das nicht.
Read steckt alle Werte (Werte= Inhalte zwischen den Worttrennern in IFS ) in die definierten Variablen, wobei die letzte den verbleibenden Rest enthält.
Die Variable IFS kannst du auch in einer Subshell setzen, so sparst du dir das Speichern.
Per default wird IFS=$' \t\n'; gesetzt. Das Bedeutet, \t Space und Newline sind nicht Bestandteil eines Feldes. Read arbeitet intern mit einer Liste!

Kleines Beispiel zur Demonstration:
Code:
wolle@Nietzsche:/tmp
$ echo "   Das ist ein Test"|(IFS=$'\n'; while read wort; do echo "$wort"; done )
   Das ist ein Test
wolle@Nietzsche:/tmp
$ echo "   Das ist ein Test IFS ist wieder das alte"|while read wort; do echo "$wort"; done
Das ist ein Test IFS ist wieder das alte


Alles Klar? ;)
Gruß Wolfgang
 
Zuletzt bearbeitet:
Hallo Wolfgang,

klar ist das hier kein 24h-Service, aber meine Frage wurde so um die
40 x angeschaut, als ich die Lösung eingetragen hatte. Und keiner
dieser 40 konnte die Lösung sofort, "so aus der Hosentasche" schreiben.
Drum hab ich mir erlaubt, in humorvollem Stil die Lösung zu posten.

Deine Erklärungen und die beiden Beispiele hab ich ausprobiert,
ich denke deutlicher kann man dies nicht mehr beschreiben, danke.
Hab mir deine Beispiele abgespeichert, werde Sie in mein Script noch
mit einarbeiten.

Im Moment knoble ich daran, mittels Rücktaste und Entfernen-Taste
die Eingabe verändern zu können, soweit ich das im Moment einschätzen
kann, hab ich dafür genügend Fakten bzw. Grundlagen, sowas zusammen
zu basteln.

Falls ich die Eingaberoutine erfolgreich zusammenkriege, werde ich sie
euch hier zur Verfügung stellen.

Nochmals besten Dank,
ist supertoll, was Ihr hier auf die Beine gestellt habt,

Manfred
 
so, versprochen ist versprochen.

Hab nun die erwähnte Eingaberoutine soweit fertig, daß ich sie für meine Zwecke verwenden kann. Selbst auf die Gefahr hin, ein paar echte Profis zum lachen zu bringen, wie ich so manches Problem dabei gelöst habe, es funktioniert erst mal.

Die Routine ist als "Unterprogramm" erstellt und für viele Zwecke einsetzbar. Gedacht für Xubuntu feisty fawn, dürfte aber auf jedem anderen Linux mit einer Shell ebenfalls laufen.

Beim Aufruf können:

- die Position des Bereiches in dem die Eingabe stattfindet
festgesetzt werden (zeile/Spalte des ersten Chars).

- die Länge der Anzeige in Buchstaben festgelegt werden,
sollte die wirkliche Eingabe länger sein, als die Anzeige,
so scrollt der eingegebene Text nach rechts bzw. nach
links hin und her (cursortasten links bzw. rechts)

- die Länge der eigentlichen Eingabe festgelegt werden.

- die Farbe der Eingabezeile kann auch angepaßt werden.

- der Einfügemodus ist fest einprogrammiert.

Hab die Routine in ein Demoprogramm gepackt, in dem vier verschieden Beispielwerte eingegeben werden können, am Ende werden die vier Variablen mit den Eingaben nochmal angezeigt.

Einzigstes, aber verschmerzliches Manko, wenn mann per Dauerfeuer Buchstaben oder Zeichen eingibt, zeigen sich auf meinem Rechner (500Mhz) ab und zu neben der Eingabeanzeige irritierende Klammern an (die wirklichen Zeichenfolgen, die die Cursortasten an das Programm senden)

Speichert euch das Script irgendwohin (/usr/sbin/eingabe.script?), ändert den Modus auf "ausführbar", geht in die Shell und ruft es auf.

Hoffe, jemand kann sowas brauchen

Code:
#! /bin/bash
#
echo ===============================================================================
echo mk_abfrage.script                Eastler               27.Aug.2007/17.Sept.2007
echo -------------------------------------------------------------------------------
# redirect 2>/dev/console # Fehlermeldungen in Datei umlenken, da die Anzeige (tty) teilw ausgeschalten wird
# --------------------------------------------------------------------------------------------------------------------------------------------------
   # VARIABLENVORGABEN:
# --------------------------------------------------------------------------------------------------------------------------------------------------
   # um Vars innerhalb aller Upros verwenden zu können, sollten sie hier im 
   # Hauptteil bereits deffiniert werden
   #
   # für die Eingaberoutine:
   vorgabe="manfred"
   EingPosX=10
   EingPosY=20
   EingFarbeVG=37
   EingFarbeHG=44
   EingFarbIntens=1
   EinLang=32
# ==================================================================================================================================================
# UNTERPROGRAMME - SUBROUTINEN
# --------------------------------------------------------------------------------------------------------------------------------------------------
FragTasteAb () {
   flag=0
   ruckgabe="keine"
   unset sondertaste
   unset zeichen
   unset umlautflag
   eingabe=$vorgabe
   nachtab=""
   vortab=$eingabe
   if [ ${#vortab} -lt $zeiglang ]
      then zeigabpos=0 ; liEnd="|"                            # wenn vorgabe kürzer als anzuzeigende Eingabebreite ist, dann Vorgab von anfang an zeigen
      else zeigabpos=$((${#vortab} - $zeiglang)) ; liEnd="<" # wenn länger, dann so, daß Ende Vorgabe rechtsbündig gezeigt wird
      fi
   if [ "$EinLang" -gt "$zeiglang" ] ; then reEnd=">" ; else reEnd="|" ; fi
   curpos=$(($EingPosX+${#vortab}-$zeigabpos))
   while [ "$ruckgabe" == "keine" ]; do
         # vortab = String-teil vor dem Cursor, nachtab das dahinter. 
         if [ $((${#vortab})) -gt $(($EinLang)) ] ; then vortab=${vortab:0:$(($EinLang))}; fi
         if [ $((${#vortab}+${#nachtab})) -gt $EinLang ] ; then nachtab=${nachtab:0:$(($(($EinLang))-${#vortab}))}; fi  #falls zu lang, nachtab kürzen
         if [ $((${#vortab}+${#nachtab})) -lt $EinLang ] ; then #falls länge vortab+länge-nachtab kleiner Eingabebreite, Spaces dranhängen
            until [ $((${#vortab}+${#nachtab})) -eq $EinLang ] ; do nachtab=$nachtab" " ; done 
         fi
         curpos=$(($EingPosX+${#vortab}-$zeigabpos))
         if [ "$curpos" -ge $(($EingPosX+$zeiglang)) ] ; then            # cursor geht über anzeige rechts raus,
              zeigabpos=$(($zeigabpos+$zeiglang/5))                      # 20% von Zeiglang nach links versetzen
              liEnd="<"
              if [ $(($zeigabpos+$zeiglang)) -ge $(($EinLang)) ] ; then  # wenn dabei zu weit gerückt wurde, korrigieren
                 zeigabpos=$(($EinLang-$zeiglang))
                 reEnd="|"
              fi
              curpos=$(($EingPosX+${#vortab}-$zeigabpos))                   # curpos neu berechnen
         fi 
         if [ "$curpos" -le "$EingPosX" ] ; then                            # cursor geht über Anzeige links raus
              zeigabpos=$(($zeigabpos-$zeiglang/5))                         # 20% von Zeiglang nach rechts versetzen
              reEnd=">"
              if [ "$zeigabpos" -le 0 ] ; then zeigabpos=0 ; liEnd="|" ; fi # wenn dabei zu weit grückt wurde, korrigieren
              curpos=$(($EingPosX+${#vortab}-$zeigabpos))                   # curpos neu berechnen
         fi
         echo -ne "\033["$EingPosY";"$curpos"H\033["$EingFarbIntens";"$EingFarbeVG";"$EingFarbeHG"m${nachtab:0:$(($zeiglang-$curpos+$EingPosX))}$reEnd"
         echo -ne "\033["$EingPosY";"$(($EingPosX-1))"H$liEnd${vortab:$(($zeigabpos)):$(($zeiglang))}\033[0m"
         zeichen=""
         org_ifs=$IFS   # (Original-) Inhalt von IFS in $org_ifs sichern
         IFS=$'\n'    # für das folgende for-in nur Zeilenschaltungen als Var-Trenner nehmen, damit Spaces auch hier ankommen
         read -s -n1 -t1 zeichen            # lese eine Sekunde lang (-t1) genau 1 Zeichen (-n1) von der Tastatur ohne Anzeige (-s)
         zeitflag="$?"                      # Rückgabefehlerwert von read in Var speichern (0=es war eine Eingabe,  1=Zeit abgelaufen (1 Sekunde) )
         IFS=$org_ifs                       # Den originalen Inhalt von IFS wieder herstellen
         case $flag in
            0) # Normalzustand, bisher kamen einfache Zeichen
               case "$zeichen" in
                  $'\x1b') flag=1 ; sondertaste=$zeichen ; zeichen="" ; echo -n "|";;         # byte war chr$(27)
                  # normale Zeichen, einfach umlaute und spaces wandeln, nur was in diesem Block hier deffiniert ist, wird erkannt
                  $'\xc3') umlautflag="gestartet" ;;  #Umlaute kommen mit 2 Zeichen rein, das erste ist immer \xc3, das zweite differenziert dann
                  $'\x96') if [ umlautflag="gestartet" ] ; then vortab=$vortab"Oe" ; umlautflag="" ; fi ;;
                  $'\x9C') if [ umlautflag="gestartet" ] ; then vortab=$vortab"Ue" ; umlautflag="" ; fi ;;
                  $'\x84') if [ umlautflag="gestartet" ] ; then vortab=$vortab"Ae" ; umlautflag="" ; fi ;;
                  $'\xB6') if [ umlautflag="gestartet" ] ; then vortab=$vortab"oe" ; umlautflag="" ; fi ;;
                  $'\xbc') if [ umlautflag="gestartet" ] ; then vortab=$vortab"ue" ; umlautflag="" ; fi ;;
                  $'\xa4') if [ umlautflag="gestartet" ] ; then vortab=$vortab"ae" ; umlautflag="" ; fi ;;
                  $'\x9f') if [ umlautflag="gestartet" ] ; then vortab=$vortab"ss" ; umlautflag="" ; fi ;;
                  " ") vortab=$vortab"_" ; umlautflag="" ;;                        # Unterstrich statt Space nehmen
                  "_") vortab=$vortab"_" ; umlautflag="" ;;                        # getippter Unterstrich (als Ersatzspace) annehmen
                  [$'\x30'-$'\x39'])  vortab=$vortab$zeichen ; umlautflag=""  ;;   # alle Zahlen annehmen
                  $'\x5a')  vortab=$vortab$zeichen ; umlautflag=""  ;;             # grosses Z annehmen
                  [$'\x61'-$'\x7a'])  vortab=$vortab$zeichen ; umlautflag=""  ;;   # alle  kleinen buchstaben und die Grossen bis Y annehmen
                  "") 
                     if [ "$zeitflag" == 0 ] ; then                           # read Zeit war nicht abgelaufen aber Eingabe ist leer = returntaste
                        eingabe=$vortab$nachtab  # EINGABEN ÜBERNEHMEN (angehängte Spaces sind noch dran)
                        # angehängte Spaces abschneiden
                        suchchar=" " 
                        while [ "$suchchar" == " " ] ; do
                          #von hinten her spaces solange abschneiden, bis kein Space mehr als letztes ist.
                          if [ "${eingabe:$((0-1)):1}" = " " ] 
                              then eingabe=${eingabe:0:$((${#eingabe}-1))}
                              else unset suchchar # while-Schleife beenden
                          fi
                        done
                        unset suchchar
                        # da mit Cur-Rechts und hinten was eingeben Spaces eingeschmuggelt werden könnten
                        # Eingabe durchgehen und Spaces zwischendrin in "_" wandeln
                        Position=0
                        while [ $(($Position)) -le ${#eingabe} ] ; do
                           if [ "${eingabe:$Position:1}" = " " ] ; then
                              eingabe=${eingabe:0:$(($Position))}"_"${eingabe:$(($Position + 1))}
                           fi
                           Position=$(($Position + 1))
                        done
                        ruckgabe="13"            # $ruckgabe ändern = eingabeschleife beenden = zurück zum aufrufprogramm
                     fi
                     ;;
                  $'\x7f')  # ZURUECK-TASTE - LETZTES ZEICHEN LOESCHEN
                     if [ ${#vortab} -gt 0 ] ; then vortab=${vortab:0:$((${#vortab}-1))} ; fi
                     umlautflag=""  
                  ;;
               esac
            ;;
            1) # Sonderzustand - voriges Zeichen war Chr$(27), Escape-Sequenz an Variable Sondertaste dranhängen 
               if [ "$zeichen" != "" ]; then  # wenn noch ein Zeichen reinkommt, dranhängen
                     sondertaste=$sondertaste$zeichen                                # weiteres byte nach Esc merken
                     case "$sondertaste" in                                          # gleich prüfen, obs schon zu ner Sondertaste passt
                        $'\x1b')    flag=0;;                                          # "Escapezeichen falls nix weiter, dann Esc" 
                        $'\x1b[D')                                                                         # "Pfeiltaste links"
                            flag=0
                            if [ ${#vortab} -gt 0 ] ; then 
                                nachtab=${vortab:0-1:1}$nachtab
                                vortab=${vortab:0:$((${#vortab}-1))}
                            fi 
                            ;;
                        $'\x1b[C')                                                                         # "Pfeiltaste rechts"
                            flag=0 
                            if [ ${#nachtab} -gt 0 ] ; then 
                                vortab=$vortab${nachtab:0:1}
                                nachtab=${nachtab:1}
                                fi
                            ;;        
                        $'\x1b[3~') flag=0 ; if [ ${#nachtab} -gt 0 ] ; then nachtab=${nachtab:1} ; fi ;;  # "Entfernen-Taste"
                        $'\x1bOF') flag=0 ; vortab=$vortab$nachtab ; nachtab=""                          # "Ende-Taste"
                                   if [ ${#vortab} -lt $zeiglang ]
                                      then zeigabpos=0 ; liEnd="|"                           # wenn vorgabe kürzer als Eingabebreite ist, dann alles
                                      else zeigabpos=$((${#vortab} - $zeiglang)) ; liEnd="<" # wenn länger, dann Ende rechtsbündig anzeigen
                                   fi
                          ;;

                        $'\x1bOH') flag=0 ; nachtab=$vortab$nachtab ; vortab=""                          # "Home-Taste / Pos1-Taste"
                                   zeigabpos=0
                          ;;
#                       $'\x1b[2~')=Einfügen $'\x1b[A')=Pfeil hoch   $'\x1b[B')=Pfeil runter   $'\x1b[5~')=Bild hoch   $'\x1b[6~') Bild runter Taste
                     esac
                  else  # leerzeichen kam rein = Zeit in read ohne Eingabe abgelaufen = Zeichenfolge Sondertaste jetzt komplett
                     case "$sondertaste" in
                        $'\x1b') flag=0 ; eingabe=$vorgabe ; nachtab="" ; vortab=$eingabe ;; # "Escapetaste"
                        *) flag=0 ;;                  # Zeichenfolge Sondertaste ist komplett da, es ist keine der vorig geprüften tasten = ignorieren
                     esac
               fi
            ;;
         esac
      done
}
# --------------------------------------------------------------------------------------------------------------------------------------------------
ZeigMaske () {
   echo -en "\033[0m"         # Farbe auf normal zurücksetzen
   clear                      # Bildschirm löschen
   echo -en "\033[0;1;37;41m" # Farbe rot einstellen
   echo "======================================================================="
   echo "Eingaberoutine    Demo der Subroutine FragTasteAb     manfred Sept 2007"
   echo "======================================================================="
   echo "Testen Sie LEERTASTE und die Zeichen öäüÖÄÜ und ß ;-)                  "
   echo "ausgefallene Sonderzeichen werden gar nicht erst angenommen.           "
   echo "                                                                       "
   echo "mit der ESCAPE-Taste werden Ihre Eingaben verworfen, mit Return beendet"
   echo "_______________________________________________________________________"
   echo "                                                                       "
   echo "                                                                       "
   echo "                                                                       "
   echo "                                                                       "
   echo "_______________________________________________________________________"
   echo " (V)orname   (N)achname  (W)ohnort  (D)ateiname                        "
   echo " (E) Programmende                                                      "
   echo "======================================================================="
   echo -ne "\033[10;2HVorname\033[10;11H ${Vorname:0:15}" ; if [ ${#Vorname} -gt 15 ] ; then echo -ne ".." ; fi
   echo -ne "\033[10;30HNachname\033[10;41H ${Nachname:0:15}" ; if [ ${#Nachname} -gt 15 ] ; then echo -ne ".." ; fi
   echo -ne "\033[12;2HWohnort\033[12;11H ${Wohnort:0:15}" ; if [ ${#Wohnort} -gt 15 ] ; then echo -ne ".." ; fi
   echo -ne "\033[12;30HDateiname\033[12;41H ${Dateiname:0:15}" ; if [ ${#Dateiname} -gt 15 ] ; then echo -ne ".." ; fi
   echo -en "\033[0m" # Farbe wieder zurücksetzen
   echo -ne "\033[17;2HGeben Sie V, N, W, D oder E ein..."
}
#===============================================================================
# Hauptroutine
#===============================================================================
   menue="wiederholen"
   unset wasjetzt
   until [ "$menue" != "wiederholen" ] ; do
         ZeigMaske
         read -n1 -s wasjetzt
         case $wasjetzt in
           "v" | "V") 
               EingPosX=11 ; EingPosY=10 ; EinLang=30 ; zeiglang=15 ; vorgabe=$Vorname
               FragTasteAb
               Vorname=$eingabe
               ;;
           "n" | "N") 
               EingPosX=41 ; EingPosY=10 ; EinLang=30 ; zeiglang=15 ; vorgabe=$Nachname
               FragTasteAb
               Nachname=$eingabe
               ;;
           "w" | "W") 
               EingPosX=11 ; EingPosY=12 ; EinLang=30 ; zeiglang=15 ; vorgabe=$Wohnort
               FragTasteAb
               Wohnort=$eingabe
               ;;
           "d" | "D")
               EingPosX=41 ; EingPosY=12 ; EinLang=30 ; zeiglang=15 ; vorgabe=$Dateiname
               FragTasteAb
               Dateiname=$eingabe
               ;;
           "e" | "E")
               clear
               echo "Ihre Eingaben waren:"
               echo "Vorname: $Vorname"
               echo "Nachname: $Nachname"
               echo "Wohnort: $Wohnort"
               echo "Dateiname: $Dateiname"
               menue="beenden" #until-Eingabeschleife beenden
               ;;
         esac
   done
echo ===============================================================================

EDIT 17.Sept 2007 von manfred: Programm hatte kleine Fehler, Programmcode korrigiert.
euer Manfred
 
Zuletzt bearbeitet:

Ähnliche Themen

Ubuntu X / dbus problem

[openSuse10.2] SATA mal wieder...

CGI laesst sich nicht ausfuehren

Zurück
Oben