ubuntuusers.de

Eingabe mit Menge vergleichen

Status: Gelöst | Ubuntu-Version: Server 10.04 (Lucid Lynx)
Antworten |

TeTesept

Anmeldungsdatum:
29. Dezember 2010

Beiträge: Zähle...

Hi,

irgendwie bekomme ich das mit den Mengen nicht hin. Ich will eigentlich nur abfragen ob die eingegeben Zahl zwischen 0 und 9 liegt. Was mache ich falsch?

if [ $1 -eq [0-9] ]  && [ $2 -eq [0-9] ]
        then
                if [ $1 -eq $2 ]
                then
                        echo "gleich"
                else
                        echo "nicht gleich"
                fi
        else
                echo "Fehler in der Eingabe"

fi

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hallo,

du kannst nicht Integervergleiche mit Pattern kombinieren. Du könntest z.B. so prüfen

if [[ $eingabe =~ "[0-9]" ]]
then
   echo "ja, das ist zwischen 0 ... 9"
else
  echo "nein, falsch"
fi

jahb

Anmeldungsdatum:
10. April 2008

Beiträge: 238

Wohnort: Reinfeld

Hm bei mir gehts nur ohne die Quotes! Scheinbar sind die mitlerweile nicht mehr nur optional sondern sogar schädlich

TeTesept

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 4

Vielen Dank für eure Hilfe!

@jahb ja ohne die Quotes geht es 😉

 if [[ $1 = [0-9] ]] && [[ $1 = [0-9] ]]

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Logisch ohne Quotes.

Denn das [0-9] soll ja schließlich von der Shell expandiert werden zu [0123456789] und das würdest Du mit Quotes blockieren. (mit Quotes meint es wörtlich "[0-9]" so wie es da steht)

Etwas sauberer wäre:

if [[ $1 == [0-9] && $2 == [0-9] ]] ; then

track

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

Servus,

wieso hast du den Test eigentlich zweimal da stehen, TeTesept? Das ist beide Male dieselbe Bedingung. ☺

Kleine Feinheiten, für’s Protokoll:

Das Folgende ist ein Test mit einem regulären Ausdruck. Heißt, irgendwo in $1 muss ein Zeichen aus der Klasse 0 bis 9 auftauchen.

1
if [[ $1 =~ [0-9] ]]; then echo passt; else echo passt nicht; fi
$ ./foo.sh 1
passt

$ ./foo.sh 12
passt

$ ./foo.sh 123a
passt 

Was ihr jetzt letztendlich habt, ist Pattern Matching. Der gesamte Ausdruck muss dem Pattern entsprechen.

1
if [[ $1 = [0-9] ]]; then echo passt; else echo passt nicht; fi
$ ./foo.sh 1
passt

$ ./foo.sh 12
passt nicht

$ ./foo.sh 123a
passt nicht 

Patterns und reguläre Ausdrücke sind übrigens nicht dasselbe. Beide Tests funktionieren auch nur mit [[, weshalb die $1 prinzipiell nicht gequotet werden muss. Das wäre nur bei Verwendung von [ nötig, aber damit gehen sowieso weder reguläre Ausdrücke noch Pattern Matching.

TeTesept

(Themenstarter)

Anmeldungsdatum:
29. Dezember 2010

Beiträge: 4

Da habe ich mich vertippt sry ☺

Ich will ja 2 Zahlen verglichen bzw. die Eingabe auf Richtigkeit prüfen($1 $2). (Siehe erster Beitag)

So habe ich das eigentlich gemein.......

  if [[ $1 = [0-9] ]] && [[ $2 = [0-9] ]]

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

Whoops, okay. Hab ich überlesen. 😉

unmensch

Anmeldungsdatum:
29. Mai 2010

Beiträge: 170

Noch eine Anmerkung (lies dir mal "Quoting" im Bash-Manual durch):

Schau dir mal die Unterschiede an:

#!/bin/bash
#beispiel.sh
if [[ $1 == [0-9] ]] && [[ $2 == [0-9] ]]
then
  echo passt
else
  echo "passt nicht"
fi
echo '$1: '"$1"
echo '$2: '"$2"

Betrachte folgenden Aufruf des Skripts:

$ ./beispiel.sh 'a == a && 0' 'b == b && 0'
passt
$1: a == a && 0
$2: b == b && 0

die Zeile mit den Markierungen wird expandiert zu:

if [[ a == a && 0 == [0-9] ]] && [[ b == b && 0 == [0-9] ]]

was nur wahre Bedingungen enthält. (obwohl die übergebenen Parameter beide nicht nur aus einer Ziffer bestehen). Im Gegensatz dazu das Skript mit korrigierter Zeile:

if [[ "$1" == [0-9] ]] && [[ "$2" == [0-9] ]]
$ ./beispiel.sh 'a == a && 0' 'b == b && 0'
passt nicht
$1: a == a && 0
$2: b == b && 0

[edit] Hier wurde expandiert zu:

if [[ 'a == a && 0' = [0-9] ]] && [[ 'b == b && 0' == [0-9] ]]

[/edit] Im zweiten Beispiel wird der Inhalt von $1 nd $2 nicht mehr interpretiert von der Bash (sondern einfach als String gesehen). Richtiges Quoting ist bei Variablen, die Benutzereingben enthalten, besonders wichtig (weil du nicht deren Inhalt bestimmst).

Grüße

Vain

Avatar von Vain

Anmeldungsdatum:
12. April 2008

Beiträge: 2510

@unmensch: Ich habe dein Beispiel 1:1 kopiert und kann es weder unter Arch (Bash 4.2.8(2)) noch unter Ubuntu 10.10 (Bash 4.1.5(1)) nachvollziehen. Ich erhalte „passt nicht“. Huh?

Das Manual sagt dazu:

Word splitting and filename expansion are not performed on the words between the ‘[[’ and ‘]]’; tilde expansion, parameter and variable expansion, arithmetic expansion, command substitution, process substitution, and quote removal are performed.

Daraus lese ich auch, dass ich das nicht quoten muss, um deinen „Angriff“ zu verhindern.

(Trotzdem: Immer quoten ist besser – außer, wenn man gezielt Effekte ausnutzen möchte. Denn wer merkt sich schon diese tausend Sonderfälle.)

theinlein

Anmeldungsdatum:
29. Dezember 2007

Beiträge: 1279

Hallo Leute,

vielleicht kann mir jemand das erklären ...

bei mir funktioniert es MIT dem Quoting (doch echt!)

Ich würde auch vermuten, dass auf Grund des Operators (der, mit der Schlange) =~ das Expndieren im String egal sein müsste.

Ich habe hier eine bash 3.1-55 - wo ist der Unterschied?

unmensch

Anmeldungsdatum:
29. Mai 2010

Beiträge: 170

Ich habe dein Beispiel 1:1 kopiert und kann es weder unter Arch (Bash 4.2.8(2)) noch unter Ubuntu 10.10 (Bash 4.1.5(1)) nachvollziehen. Ich erhalte „passt nicht“. Huh?

Stimmt. Als ich den Thread gelesen hatte, hatte ich mir überlegt, ob das Quoting an dieser Stelle notwendig wäre, wollte es ausprobieren und war von dem Ergebnis selbst überrascht. Inzwischen weiß ich auch nicht mehr, was ich vorher anders gemacht hatte und mit meinem letzten Post krieg ich auch nur "passt nicht". Tschuldigung. Und danke für die Korrektur.

Das Manual sagt dazu:

Hatte ich auch gelesen und gedacht, dass Wordsplitting für die Conditional Expressions nicht notwendig wäre (das ist ja kein neuer Befehl, nur die Expression).

@theinlein:

bei mir funktioniert es MIT dem Quoting (doch echt!)

Was genau funktioniert bei dir?

Grüße

unmensch

Anmeldungsdatum:
29. Mai 2010

Beiträge: 170

Jetzt hab ich immerhin heraus, was ich ursprünglich gemacht hatte:

if [[ $1 =~ [0-9] ]] && [[ $2 =~ [0-9] ]]

Mit =~ statt == oder = funktioniert es, wie von mir beschrieben. Jetzt bin ich aber doch etwas verwirrt. Kann mir das jemand erklären?

Grüße

edit: Übrigens mit Bash 4.1.5(1)

track

Avatar von track

Anmeldungsdatum:
26. Juni 2008

Beiträge: 7174

Wohnort: Wolfen (S-A)

Das hat Vain doch hier oben bereits sauber auseinander gelegt ...

Lies das einfach nochmal durch, dann brauchen wir es nicht wiederholen.

LG,

track

unmensch

Anmeldungsdatum:
29. Mai 2010

Beiträge: 170

@theinlein

bei mir funktioniert es MIT dem Quoting (doch echt!) Ich würde auch vermuten, dass auf Grund des Operators (der, mit der Schlange) =~ das Expndieren im String egal sein müsste. Ich habe hier eine bash 3.1-55 - wo ist der Unterschied?

Jetzt versteh ich, was du meinst. Neuere Bashs machen das alte Verhalten mit

$ shopt -s compat31
$ [[ 0 =~ "[0-9]" ]] && echo passt
passt

Im 3.1-Bash-Manual ist die Möglichkeit, rechts von =~ zu quoten auch nicht aufgeführt.

Grüße

Antworten |