Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
-
joe2017
- Beiträge: 1274
- Registriert: 07.08.2017 14:29:51
Beitrag
von joe2017 » 11.09.2023 07:59:34
Guten morgen zusammen,
ich habe aktuell ein Script bei welchem ich abfrage ob mein Hostname einen String beinhaltet. Das funktioniert soweit auch.
Code: Alles auswählen
if [[ $HOSTNAME =~ .*0123.* ]] || [[ $HOSTNAME =~ .*3456.* ]] || [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
Jedoch möchte ich das Ganze jetzt umgedreht abfragen. Wenn der Hostname nicht beinhaltet...
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] || [[ $HOSTNAME =~ .*3456.* ]] || [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
Jodoch funktioniert das nur bei der ersten Abfrage (0123)
Was mache ich hier falsch?
Zuletzt geändert von
joe2017 am 11.09.2023 10:14:52, insgesamt 1-mal geändert.
-
Meillo
- Moderator
- Beiträge: 9241
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 11.09.2023 08:29:09
joe2017 hat geschrieben: 11.09.2023 07:59:34
Was mache ich hier falsch?
Du hast eine falsche Vorstellung der Assoziativitaet.
Loesungsweg 1: Du machst ein Ausrufezeichen vor jeden der Tests. Also:
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] && ! [[ $HOSTNAME =~ .*3456.* ]] && ! [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
Loesungsweg 2: Du ziehst die Veroderung in einen grossen Test rein:
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* -o $HOSTNAME =~ .*3456.* -o $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
Btw: Du solltest $HOSTNAME in Double-Quotes setzen.
Nachtrag: Eine ehemaliger Kollege von mir hat das Problem immer so geloest:
Code: Alles auswählen
if [[ $HOSTNAME =~ .*0123.* ]] || [[ $HOSTNAME =~ .*3456.* ]] || [[ $HOSTNAME =~ .*7890.* ]]; then
: # do nothing
else
echo "yes"
fi
Zuletzt geändert von
Meillo am 11.09.2023 10:08:18, insgesamt 3-mal geändert.
Grund: Korrekturen nach heisenbergs und tobos Hinweisen
Use ed once in a while!
-
heisenberg
- Beiträge: 4123
- Registriert: 04.06.2015 01:17:27
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von heisenberg » 11.09.2023 09:15:40
Meillo hat geschrieben: 11.09.2023 08:29:09
Loesungsweg 1: Du machst ein Ausrufezeichen vor jeden der Tests. Also:
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] || [[ $HOSTNAME =~ .*3456.* ]] || [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
Du meintest wohl das?
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] || ! [[ $HOSTNAME =~ .*3456.* ]] || ! [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
-
Meillo
- Moderator
- Beiträge: 9241
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 11.09.2023 09:20:55
Sorry, ja, natuerlich.
Hab's korrigiert.
Use ed once in a while!
-
tobo
- Beiträge: 2362
- Registriert: 10.12.2008 10:51:41
Beitrag
von tobo » 11.09.2023 09:39:18
Das wäre dann aber ein logischer Fehlschluss!
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] && ! [[ $HOSTNAME =~ .*3456.* ]] && ! [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
## oder
if ! { [[ $HOSTNAME =~ .*0123.* ]] || [[ $HOSTNAME =~ .*3456.* ]] || [[ $HOSTNAME =~ .*7890.* ]]; } then
echo "yes"
fi
-
Meillo
- Moderator
- Beiträge: 9241
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 11.09.2023 09:48:19
tobo hat geschrieben: 11.09.2023 09:39:18
Das wäre dann aber ein logischer Fehlschluss!
Was waere ein logischer Fehlschluss? Auf welchen Befehl beziehst du dich?
Btw: Alternativ koennte man es mit `case' loesen:
Code: Alles auswählen
case "$HOSTNAME" in
*0123*|*3456*|*7890*) ;;
*) echo yes ;;
esac
(Hier wird allerdings Globbing und nicht Regexps verwendet!)
Use ed once in a while!
-
tobo
- Beiträge: 2362
- Registriert: 10.12.2008 10:51:41
Beitrag
von tobo » 11.09.2023 09:57:12
Meillo hat geschrieben: 11.09.2023 09:48:19
tobo hat geschrieben: 11.09.2023 09:39:18
Das wäre dann aber ein logischer Fehlschluss!
Was waere ein logischer Fehlschluss? Auf welchen Befehl beziehst du dich?
Das
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] || ! [[ $HOSTNAME =~ .*3456.* ]] || ! [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
ist immer "yes".
-
Meillo
- Moderator
- Beiträge: 9241
- Registriert: 21.06.2005 14:55:06
- Wohnort: Balmora
-
Kontaktdaten:
Beitrag
von Meillo » 11.09.2023 10:09:18
... vielleicht sollte ich heute das Posten besser lassen. Du hast voellig recht.
(Ich hab's oben nochmal angepasst.)
Use ed once in a while!
-
joe2017
- Beiträge: 1274
- Registriert: 07.08.2017 14:29:51
Beitrag
von joe2017 » 11.09.2023 10:14:39
Also mit folgendem hab ich es erfolgreich getestet...
Code: Alles auswählen
if ! { [[ $HOSTNAME =~ .*0123.* ]] || [[ $HOSTNAME =~ .*3456.* ]] || [[ $HOSTNAME =~ .*7890.* ]]; } then
echo "yes"
fi
Vielen Dank
-
tobo
- Beiträge: 2362
- Registriert: 10.12.2008 10:51:41
Beitrag
von tobo » 11.09.2023 10:32:47
Nur zur Vervollständigung - das ist auch dann logisch true, wenn HOSTNAME nicht existiert oder leer ist. Für den Fall, dass dads Relevanz hat und du noch eine Prüfung davor setzen willst.
-
heisenberg
- Beiträge: 4123
- Registriert: 04.06.2015 01:17:27
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von heisenberg » 11.09.2023 10:36:33
tobo hat geschrieben: 11.09.2023 09:57:12
Meillo hat geschrieben: 11.09.2023 09:48:19
... Auf welchen Befehl beziehst du dich?
Das
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] || ! [[ $HOSTNAME =~ .*3456.* ]] || ! [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
ist immer "yes".
Also dann doch eher so:
Code: Alles auswählen
if ! [[ $HOSTNAME =~ .*0123.* ]] && ! [[ $HOSTNAME =~ .*3456.* ]] && ! [[ $HOSTNAME =~ .*7890.* ]]; then
echo "yes"
fi
# !(a || b) <=> !a && !b
-
tobo
- Beiträge: 2362
- Registriert: 10.12.2008 10:51:41
Beitrag
von tobo » 11.09.2023 11:33:59
Ich sehe da jetzt nicht "den" Unterschied:
Code: Alles auswählen
$ for a in false true; do for b in false true; do echo -n "!($a || $b) --> "; if ! ( `$a` || `$b` ); then echo TRUE; else echo FALSE; fi; done; done
!(false || false) --> TRUE
!(false || true) --> FALSE
!(true || false) --> FALSE
!(true || true) --> FALSE
$ for a in false true; do for b in false true; do echo -n "! $a && ! $b --> "; if ! `$a` && ! `$b`; then echo TRUE; else echo FALSE; fi; done; done
! false && ! false --> TRUE
! false && ! true --> FALSE
! true && ! false --> FALSE
! true && ! true --> FALSE
$
-
heisenberg
- Beiträge: 4123
- Registriert: 04.06.2015 01:17:27
- Lizenz eigener Beiträge: MIT Lizenz
Beitrag
von heisenberg » 11.09.2023 11:38:42
tobo hat geschrieben: 11.09.2023 11:33:59
Ich sehe da jetzt nicht "den" Unterschied:
Code: Alles auswählen
$ for a in false true; do for b in false true; do echo -n "!($a || $b) --> "; if ! ( `$a` || `$b` ); then echo TRUE; else echo FALSE; fi; done; done
!(false || false) --> TRUE
!(false || true) --> FALSE
!(true || false) --> FALSE
!(true || true) --> FALSE
$ for a in false true; do for b in false true; do echo -n "! $a && ! $b --> "; if ! `$a` && ! `$b`; then echo TRUE; else echo FALSE; fi; done; done
! false && ! false --> TRUE
! false && ! true --> FALSE
! true && ! false --> FALSE
! true && ! true --> FALSE
$
Ja genau. Es soll ja auch identisch sein. Der Fehler, den Du zurecht kritisiert hattest, war, dass die Umformung (von Meillo) nicht korrekt war.
Zuletzt geändert von
heisenberg am 11.09.2023 11:50:14, insgesamt 1-mal geändert.
-
tobo
- Beiträge: 2362
- Registriert: 10.12.2008 10:51:41
Beitrag
von tobo » 11.09.2023 11:47:50
Ok, dann hatte ich das falsch verstanden.