[bash] if-Abfrage mit RegEx

J

jahsoldier

Grünschnabel
Hallo,

ich möchte in einem Bash-Skript prüfen, ob die an das Skript übergebene Variable "src_ip" eine IPv4-Adresse ist. Eine detaillierte Prüfung auf gültige Addressen (<255) ist für mich dabei nicht relevant. Daher habe ich folgende if-Abfrage konstruiert:

Code:
if [[ "$src_ip" != "[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}\.[0-9]\{1,3\}" ]]; then
    error=1
fi

Diese funktioniert aber leider nicht und ich komme zu keiner Lösung! Kann mir da bitte jemand weiterhelfen?

Grüße
 
hi,

du hattest fast alles richtig:

Code:
if [[ "$ip" =~ '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ]]; then
	echo "equal"
fi

Das checkt jetzt natuerlich ob es gleich ist.

mfg,
bytepool
 
Wenn ich das jetzt richtig sehe, benötige ich einfache Anführungszeichen für Regular Expression, oder?

Es funktioniert damit aber leider immer noch nicht, was mache ich noch falsch?

Code:
# set example ip
src_ip=192.168.2.114

if [[ "$src_ip" != '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' ]]; then
    error=1
fi

Grüße
 
Hallo
Code:
error=1
Macht erstmal garnichts.
Wenn du schon mit einer Errorvariablen arbeiten willst, dann musst du die schon selbst auswerten (und vorher initialisieren!).

Gruß Wolfgang
EDIT: Und ja, du brauchts doppelte ". Bei einfachem Hochkomma werden die [ u.A. Zeichen nicht interpretiert, bleiben also so stehen!
 
Zuletzt bearbeitet:
Hallo,

vielen Dank für Eure Antworten. Ich habe inzwischen eine Möglichkeit gefunden, die folgendermaßen aussieht:

Code:
if ! [[ "$src_ip" =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then
    error=1
fi

An Wolfgang:

Du hättest vielleicht erahnen können, dass dies nur ein Ausschnitt aus einen Skript ist, speziell aus einer von mir definierten Funktion check_arguments, um genau zu sein. Diese überprüft die an das Skript übergebenen Parameter. Die IP-Adresse ist dabei nicht der einzigste Parameter und error dient nur zur Kennzeichnung eines Fehlers und wird erst nach Abarbeitung aller Parameter überprüft. Falls es Dich interessiert, hier die ganze Funktion:

Code:
# General settings
...
ARGUMENT_NOT_PRESENT=2                         # return code of check_arguments
...
#------------------------------------------------------------------------------#
# check_arguments()                                                            #
# Checks if all arguments for script.sh exists                                 #
# Parameters: none                                                             #
# Return value: 0 if successful, $ARGUMENT_NOT_PRESENT if not                  #
#------------------------------------------------------------------------------#
function check_arguments()
{
    # check source ip address
    if ! [[ "$src_ip" =~ ([0-9]{1,3}\.){3}[0-9]{1,3} ]]; then
       error=1
    fi

    # check source port
    if [ "$src_port" != "$source_port" ]; then
        error=1
    fi
    # check destination port
    if [ "$dest_port" != "$knock_port" ] && [ $dest_port != "$knock_service" ]; then
        error=1
    fi
    # check sequence number
    if [ "$seq_number" != "$sequence_number" ]; then
        error=1
    fi
    # check window
    if [[ "$window" < "0" ]] || [[ "$window" > "65535" ]]; then
        error=1
    fi

    if [ $error -eq 1 ]; then
        return $ARGUMENT_NOT_PRESENT
    fi
    return 0
}
...
# temporary variables
error=0                               # initialize as Null
...
check_arguments
...
 
Hallo,

vielen Dank für Eure Antworten. Ich habe inzwischen eine Möglichkeit gefunden, die folgendermaßen aussieht:

Code:
if ! [[ "$src_ip" =~ [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} ]]; then
    error=1
fi

An Wolfgang:

Du hättest vielleicht erahnen können, dass dies nur ein Ausschnitt aus einen Skript ist, speziell aus einer von mir definierten Funktion check_arguments, um genau zu sein. Diese überprüft die an das Skript übergebenen Parameter. Die IP-Adresse ist dabei nicht der einzigste Parameter und error dient nur zur Kennzeichnung eines Fehlers und wird erst nach Abarbeitung aller Parameter überprüft.

Ja das hätte ich. Aber wenn nach einem Fehler gefragt wird, gebe ich generell Hinweise, die aus den gegebenen Informationen schließend, zu allen möglichen Fehlern führen können.
Sorry, aber meine Glaskugel ist noch eine Experimental Version. ;)
 
Ich habe inzwischen eine Möglichkeit gefunden, die folgendermaßen aussieht:

Nichts anderes hatte ich in meinem ersten Post geschrieben. Ich war frecherweise einfach mal davon ausgegangen, dass du auf die Idee mit dem 'not' davor dann selber kommst :P

mfg,
bytepool
 
Hi bytepool,

Deine Methode hat bei mir leider noch nicht funktioniert. Ich musste zusätzlich noch die einfachen Anführungszeichen entfernen. Aber das hätte ich auch erwähnen können. Mein Fehler.

Grüße
 
Ahso, na dann. Bei meiner Bash Version funktioniert es egal mit welchen Anfuehrungszeichen.
Was eigentlich auch meinem Verstaendnis des ganzen Vorgangs entspricht, weil zuerst die Variablen Substitution etc. durchgefuehrt wird (der Schritt in dem die Art der Anfuehrungszeichen entscheidend ist), und dann erst der Vergleich mit =~ kommt. Und die regex wird eigentlich erst von =~ ausgewertet, so dass es in diesem konkreten Fall (ohne Variablen in der regex) egal sein sollte welche Anfuehrungszeichen man verwendet. Naja, egal ;)

edit:
Und in deinem 2ten Post hast du immer noch den falschen Operator verwendet, != statt =~.

edit2:
Und die von dir zuletzt gepostet Loesung funktioniert bei dir?
Code:
if ! [[ "$src_ip" =~ ([0-9]{1,3}\.){3}[0-9]{1,3} ]]; then
Denn das fuehrt bei mir zu einem Syntax Fehler, da die Bash mit der oeffnenden Klammer '(' nicht klar kommt. Jetzt hast du mich doch neugierig gemacht welche Bash Version du eigentlich verwendest ;)
Wie gesagt, unter GNU bash, version 3.1.17(1)-release (x86_64-pc-linux-gnu) funktioniert das so nicht, der Ausdruck MUSS dann gequotet werden.

Achja, und mir ist auch grade noch ein kleiner Fehler bei deiner regex aufgefallen. Zur Zeit guckt er nur, ob die typische IPv4 Struktur in der Zeichenkette vorkommt, d.h. auch "120.44.44.4555" und "12055.44.44.45" sind nach dieser Definition gueltige IP Adressen. Abhilfe schafft '^([0-9]{1,3}\.){3}[0-9]{1,3}$'.

mfg,
bytepool
 
Zuletzt bearbeitet:
Hi bytepool,

danke für Deine Hinweise, aber diese funktionieren bei mir leider nicht. Einfache Anführungszeichen erzeugen zwar keine Fehlermeldung, aber der Test
Code:
src_ip=192.168.2.1
! [[ "$src_ip" =~ '([0-9]{1,3}\.){3}[0-9]{1,3}' ]]
liefert 0 zurück. Auch mit Deiner RegEx konnte ich immer noch IP-Adressen wie 12055.44.44.45 übergeben. Das wäre aber eine tolle Sache. Vielleicht hast Du eine Idee woran das liegt! Hier meine Systeminfos:

Code:
[root@jahsoldier]# lsb_release -a
Distributor ID: Ubuntu
Description:    Ubuntu 7.10
Release:        7.10
Codename:       gutsy
[root@jahsoldier]# uname -a
Linux jahsoldier 2.6.22-14-generic #1 SMP Tue Dec 18 08:02:57 UTC 2007 i686 GNU/Linux
[root@jahsoldier]# echo $BASH_VERSION
3.2.25(1)-release

Grüße
 
hi,

es scheint in der Tat an den unterschiedlichen Bash Versionen zu liegen, auf meinem Laptop habe ich auch Version 3.2.25, und waehrend der von mir oben gepostete code unter 3.1.17 einwandfrei funktioniert, verhaelt er sich unter der neuen Version nicht so wie er sollte.
Sehr merkwuerdig, ich wuerde fast vermuten dass das ein bug von der bash ist...
Ich schau mal ob ich eine Loesung finde, kann ja irgendwie nicht angehen...

edit:
Mhh, ja, es liegt scheinbar in der Tat an den Anfuehrungszeichen.
Unter Version 3.2.25 funktioniert das hier:
Code:
if ! [[ "$src_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then

Entweder ist das ein Bug, oder aber sie haben in der Reihenfolge der Auswertung was geaendert. Ich versteh's jedenfalls nicht.

edit2:
Sie haben da jedenfalls was geaendert, das hier steht im changelog unter features:
f. Quoting the string argument to the [[ command's =~ operator now forces
string matching, as with the other pattern-matching operators.
quelle: http://tiswww.case.edu/php/chet/bash/CHANGES

Also wie heisst das so schoen: It's not a bug, it's a feature ;)

mfg,
bytepool
 
Zuletzt bearbeitet:

Ähnliche Themen

NAS-Drive Mount in Bash-Script über crontab

[Gelöst] Suchen und ersetzen mit Hilfe mehrerer Parameter

Kill Skript

mittels if abfrage datei nach variabelnwert durchsuchen

Shellskript - Fehler in Cron

Zurück
Oben