while

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von Jo8558, 30.08.2012.

  1. Jo8558

    Jo8558 Grünschnabel

    Dabei seit:
    28.08.2012
    Beiträge:
    7
    Zustimmungen:
    0
    Ich hoffe jetzt mal das die Frage noch nicht gestellt wurde!

    Wieso funzt das nicht? Es ist eine einfache ja nein frage, bei der verhindert werden soll das man was anderes als Y oder N eingibt:

    echo "Enter your answer (Y or N)"
    read answer
    while [ $answer = "" ] && [ $answer != Y ] && [ $answer != y ] && [ $answer != N ] && [ $answer != n ]
    do
    echo "Enter your answer (Y or N)"
    read answer
    done
    ...

    es funktioniert wenn man den ersten teil des while weglässt aber ich will ja verhindern das der user einfach auf Enter drückt

    lg
    Jo
     
  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 tgruene, 30.08.2012
    tgruene

    tgruene Routinier

    Dabei seit:
    02.02.2012
    Beiträge:
    418
    Zustimmungen:
    0
    Code:
    while [  $answer = "" ] && ... 
    Wenn ich irgendwas ausser Y|y|n|N eingeben, z.B. 'Nein', dann ist diese Bedingung schon falsch, so dass die Schleife unterbrochen wird.
    Lass das
    Code:
    [  $answer = "" ] &&
    mal weg!
     
  4. Jo8558

    Jo8558 Grünschnabel

    Dabei seit:
    28.08.2012
    Beiträge:
    7
    Zustimmungen:
    0
    richtig, ich will das man nur Y|y|n|N eingeben kann, wenn ich das [ $answer = "" ] weglasse funktioniert das man nur Y|y|n|N eingeben kann aber dann bekomme ich eine fehlermeldung wenn ich einfach enter drücke und er spring nicht in die while loop
     
  5. #4 Gast123, 30.08.2012
    Gast123

    Gast123 Guest

    Wie wäre es mit sowas?
    Code:
    # Ask a question and return 0 on 'yes' or 1 on 'no'
    ask() {
    
    	USAGE="\
    	Usage: ask [The yes / no question]\nReturns 0 on \"y\" or 1 on \"n\"."
    
    	if [ $# -lt 1 ]; then
    		echo -e $USAGE
    		return 2
    	fi
    
    	echo -n "$@ [y/n]: " 
    	read ANSWER
    	shopt -s nocasematch
    	case "$ANSWER" in
    		j|y|ja|yes)
    			return 0;;
    		n|no|nein)
    			return 1;;
    		*)	
    			ask "Please enter 'yes' or 'no'"
    			return $?;;
    	esac
    }
     
  6. Jo8558

    Jo8558 Grünschnabel

    Dabei seit:
    28.08.2012
    Beiträge:
    7
    Zustimmungen:
    0
    is das nicht ein wenig gar aufwendig nur damit ich verhindern kann das der user einfach auf enter drückt? ;) oder gibt es keine andere möglichkeit?

    lg
     
  7. #6 Gast123, 30.08.2012
    Gast123

    Gast123 Guest

    Ich sehe da jetzt keinen großen Aufwand in der Funktion. Du kannst ja gerne auch die Hilfeausgabe weglassen:
    Code:
    ask() {
    	echo -n "$@ [y/n]: " 
    	read ANSWER
    	shopt -s nocasematch
    	case "$ANSWER" in
    		j|y|ja|yes)
    			return 0;;
    		n|no|nein)
    			return 1;;
    		*)	
    			ask "Please enter 'yes' or 'no'"
    			return $?;;
    	esac
    }
    PS: Falls es dir nur darum geht, dass nicht einfach "Enter" gedrückt wird, ohne das Ergebnis abzufragen, kannst du den Benutzer mit
    Code:
    ANSWER=""; while [ -z "$ANSWER" ]; do read ANSWER; done
    beliebig lang nerven. :D
     
  8. #7 tgruene, 30.08.2012
    tgruene

    tgruene Routinier

    Dabei seit:
    02.02.2012
    Beiträge:
    418
    Zustimmungen:
    0
    Stimmt - wobei ich den Effekt auch mit der leeren Abfrage bekomme, bzw. eine Fehlermeldung bzgl. 'while'. 'if' scheint damit weniger Probleme zu haben, das folgende Skript funktioniert beim ersten Test:
    Code:
    read -p "Enter your answer (Y or N)" answer
    if [ -z $answer ]; then answer="weiterfragen"; fi
    
    while [ $answer != Y ] && [ $answer != y ] && [ $answer != N ] && [ $answer != n ] 
    do
            read -p "Enter your answer (Y or N)" answer
            if [ -z $answer ]; then answer="weiterfragen"; continue; fi
    done
    
     
  9. #8 Gast123, 30.08.2012
    Gast123

    Gast123 Guest

    Ich glaube, ich verstehe nun, was du haben möchtest.
    Du solltest den auszuwertenden Ausdruck komplett an while übergeben:
    Code:
    ANSWER=""; while [ "$ANSWER" != "y" -a "$ANSWER" != "Y" -a "$ANSWER" != "n" -a "$ANSWER" != "N" ]; do read -p "Enter your answer (Y or N)" ANSWER; done
     
  10. #9 tgruene, 30.08.2012
    tgruene

    tgruene Routinier

    Dabei seit:
    02.02.2012
    Beiträge:
    418
    Zustimmungen:
    0
    Weswegen funktioniert dieses Skript:
    Code:
    ANSWER="";
    while [ -z $ANSWER ] || [ $ANSWER != Y ] && [ "$ANSWER" != 'N' ]; do
            read -p "Eingabe: " ANSWER;
    done
    
    dieses auch:
    Code:
    answer="";
    while [ -z $answer ] || [ "$answer" != 'Y' ] && [ "$answer" != 'y' ] && [ "$answer" != 'N' ] && [ "$answer" != 'n' ]
    do
    read -p "Enter your answer (Y or N)" answer;
    done
    
    aber nur, wenn man ausser in der 'Y'-Abfrage, die '$answer' in Anfuehrungszeichen setzt? In der (ersten nach ||) Abfrage nach 'Y' kann man sie weglassen. Weswegen ist das so?
     
  11. #10 Gast123, 30.08.2012
    Gast123

    Gast123 Guest

    Wenn im ersten Durchlauf
    Code:
    $answer
    ausgewertet wird, ist es der leere String.
    Also steht für die bash da
    Code:
    test "" != 'Y'
    , was wahr ist.
    Würdest du die Anführungszeichen weglassen (bitte, bitte, nie bei Strings machen!), stünde für die bash da
    Code:
    test != 'Y'
    , was keinen Sinn ergibt!
     
  12. marce

    marce Kaiser

    Dabei seit:
    01.08.2007
    Beiträge:
    1.056
    Zustimmungen:
    8
    Google einfach mal "bash stringvergleich" (oder einem entsprechenden Ausdruck in Englisch) - oder schau in den üblichen Bash-Tutorials nach.

    Syntax ist halt Syntax.
     
  13. #12 tgruene, 31.08.2012
    tgruene

    tgruene Routinier

    Dabei seit:
    02.02.2012
    Beiträge:
    418
    Zustimmungen:
    0
    @Schard/ @marce:
    Das ist mir schon klar. Meine Frage war, weswegen dieses Skript:
    Code:
    while [ -z $ANSWER ] || [ $ANSWER != Y ] && [ "$ANSWER" != 'N' ]; do
            read -p "Eingabe: " ANSWER;
    done
    echo "Antwort: $ANSWER"
    
    funktioniert, waehrend dieses Skript
    Code:
    while [ -z $ANSWER ] || [ $ANSWER != Y ] && [ $ANSWER != 'N' ]; do
            read -p "Eingabe: " ANSWER;
    done
    echo "Antwort: $ANSWER"
    
    beim Aufruf den Fehler
    Code:
    while.sh: line 1: [: !=: unary operator expected
    ergibt. Beim ersten logischen Ausdruck der '&&'-Kette scheinen keine Anfuehrungszeichen vonnoeten zu sein, nur bei den restlichen.
     
  14. #13 Gast123, 31.08.2012
    Gast123

    Gast123 Guest

    @tgruene: Und genau das habe ich in Post #10 beschrieben. :D
    Der erste Teil der logischen Kette hat nur einen unären Operator, und das Resultat ist wahr.
    Code:
    test -z $ANSWER
    expandiert zu
    Code:
    test -z 
    Da das wahr ist, wird der Block nach dem
    Code:
    ||
    gar nicht ausgeführt, sondern es wird zum Block nach dem
    Code:
    &&
    gesprungen.
    Und dieser funktioniert wie in #10 beschrieben nicht:
    Code:
    test != 'Y'
    bash: test: !=: Einstelliger (unärer) Operator erwartet.
    MfG

    Schard
     
  15. Anzeige

    Vielleicht findest du HIER Antworten.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  16. #14 tgruene, 01.09.2012
    tgruene

    tgruene Routinier

    Dabei seit:
    02.02.2012
    Beiträge:
    418
    Zustimmungen:
    0
    Hallo Schard,
    ich war davon ausgegangen, dass && staerker bindet als ||, d.h., dass
    Code:
     A || B && C 
    auch in der bash aequivalent ist zu
    Code:
     A || ( B && C)
    so wie hier ganz unten beschrieben. Vielleicht wertet bash bei (A&&B) zuerst B aus. Eigentlich ist die Diskussion muessig, da es ja eigentlich guter Programmierstil ist, Anfuehrungszeichen und Klammer zu setzen.
     
  17. #15 Gast123, 01.09.2012
    Gast123

    Gast123 Guest

    @tgruene:
    Nein, nein, nein. :)
    Die Operatoren
    Code:
    ||
    und
    Code:
    &&
    werten zuvorige Rückgabewerte von Programmen und Funktionen aus und führen dann entsprechend das folgende Statement aus.
    Code:
    A || B
    heißt, dass B genau dann ausgeführt wird, wenn der Rückgabewert von A sich von 0 unterscheidet (nicht Null ist).
    Code:
    A && B
    heißt, dass B genau dann ausgeführt wird, wenn der Rückgabewert von A gleich 0 ist.
    Dein Beispiel
    Code:
     A || B && C
    bedeutet, dass B genau dann ausgeführt wird, wenn der Rückgabewert von A sich von 0 unterscheidet. Und C wird genau dann ausgeführt, wenn der Rückgabewert von A oder B gleich 0 ist.

    MfG

    Schard
     
Thema: while
Besucher kamen mit folgenden Suchen
  1. While (1) { ask();}

Die Seite wird geladen...

while - Ähnliche Themen

  1. do-while Schleife

    do-while Schleife: Hi, Ich sehe bei Bash immer nur: while [ Bedingung ]; do Aktion done Gibt es auch eine umgekehrte Schleife? Also do...
  2. while loop - ich blicks nicht

    while loop - ich blicks nicht: Moin ich hab da irgendwie ein Problem, ich raffs nicht so ganz was da falsch läuft. Vielleicht kann mir einer von euch kurz sagen was da falsch...
  3. while [ 1 = 1 ] ...Anfängerfrage

    while [ 1 = 1 ] ...Anfängerfrage: Hi, Warum gibt: while [ 1 = 1 ] ; do echo -n '.' && sleep 1 ; done ..mal einen und mal zwei Punkte auf einmal aus? Müsste es nicht immer nur...
  4. Expect - Fehler in While

    Expect - Fehler in While: Hi, versuche mich gerade mit Expect und bin dabei, ein File zeilenweise auszulesen, wobei das erste Argument ein Host und das zweite ein...
  5. error while loading shared libraries: libstdc++.so.6: cannot open shared object file:

    error while loading shared libraries: libstdc++.so.6: cannot open shared object file:: Hallo, Ich habe hiermit gerade ein Problem: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file...