eingaberoutine in bash - space mit read

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von manfred, 27.08.2007.

  1. #1 manfred, 27.08.2007
    manfred

    manfred Jungspund

    Dabei seit:
    27.08.2007
    Beiträge:
    10
    Zustimmungen:
    0
    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
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 manfred, 28.08.2007
    manfred

    manfred Jungspund

    Dabei seit:
    27.08.2007
    Beiträge:
    10
    Zustimmungen:
    0
    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
     
  4. #3 Wolfgang, 28.08.2007
    Zuletzt bearbeitet: 28.08.2007
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    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. ;)
    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
     
  5. #4 manfred, 29.08.2007
    manfred

    manfred Jungspund

    Dabei seit:
    27.08.2007
    Beiträge:
    10
    Zustimmungen:
    0
    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
     
  6. #5 manfred, 04.09.2007
    Zuletzt bearbeitet: 17.09.2007
    manfred

    manfred Jungspund

    Dabei seit:
    27.08.2007
    Beiträge:
    10
    Zustimmungen:
    0
    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
     
Thema: eingaberoutine in bash - space mit read
Besucher kamen mit folgenden Suchen
  1. bash abfangen passwort

    ,
  2. bash read 1-zeichen

    ,
  3. bash read p leerzeichen ersetzen

Die Seite wird geladen...

eingaberoutine in bash - space mit read - Ähnliche Themen

  1. Bräuchte Hilfe bei Backupscript mittels Bash und cronjob

    Bräuchte Hilfe bei Backupscript mittels Bash und cronjob: Es soll für bestimmte Ordner Archivierung aller Dateien(Logfiles), die älter als 30 Tage sind machen. Am besten einmal täglich nachts irgendwann....
  2. Bashscript aus Debian6 läuft nicht auf Debian7

    Bashscript aus Debian6 läuft nicht auf Debian7: Hallo an alle, nachdem ich ein Skript von squeeze auf wheezy kopiert habe und ausführte, erschienen gleich wilde Fehlermeldungen, nach denen ich...
  3. Bash sucht neues Logo

    Bash sucht neues Logo: Die GNU Bourne Again Shell (bash) sucht nach knapp 20 Jahren ein neues, individuelles Logo. Alle Anwender und Interessenten sind deshalb...
  4. Mit bash Skript bestimmte Werte aus Tabelle lesen

    Mit bash Skript bestimmte Werte aus Tabelle lesen: Hallo! Ich beschäftige mich erst seit Kurzem mit bash und bin deshalb noch nicht so fit darin. Und nun habe ich schon ein kleines Problem und...
  5. Bash: Geteiltes Fenster mit unterschiedlichen Funktionen

    Bash: Geteiltes Fenster mit unterschiedlichen Funktionen: Hallo Leute, ist es in Bash möglich, zwei Funktionen in zwei getrennten Teilen eines Terminalfensters ablaufen zu lassen? Da Bash die Befehle...