Bash IF Abfrage, Befehl, Subshell ?

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
weedy
Beiträge: 585
Registriert: 02.11.2002 21:47:49
Lizenz eigener Beiträge: GNU General Public License
Kontaktdaten:

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von weedy » 18.01.2017 17:58:10

ren22 hat geschrieben:Hallo,

Code: Alles auswählen

#!/bin/bash

testvariable=foo
if [ $(echo "$testvariable" | grep "foo" ) ] ; then
		echo "foooo"
fi

if [ echo "$testvariable" | grep "foo" ] ; then
		echo "foooo"
fi
warum muss man die Abfrage mit "grep" in eine Subshell packen und kann den Code nicht so ausführen wie in der 2ten IF Abfrage des Codebeispiels ohne
das es eine Fehlermeldung gibt:
line 8: [: missing `]'
grep: ]: No such file or directory?

möchte ich man test ? Oder wo kann man dies bzgl. nachlesen ?

Danke
Lass die Klammern einfach weg.

Code: Alles auswählen


+$ testvariable=foo
+$ if echo "$testvariable" | grep "foo"; then
+>  echo fooo
+> fi
foo
fooo


Gruß

breakthewall
Beiträge: 507
Registriert: 30.12.2016 23:48:51

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von breakthewall » 18.01.2017 19:18:45

Meillo hat geschrieben:Ausserdem wissen die wenigsten ueber solche Feinheiten Bescheid und dann schreiben sie die `['-Variante auch ohne Quotes. Unzureichendes Quoting ist eines der groessten Robustheitsprobleme beim Shellscripten.
Aus dieser Sicht ist das natürlich einleuchtend, dass man das gewissermaßen einheitlich hält. Ebenso die Nutzung von Backticks kann sehr verwirrend sein, wenn $(...) doch viel sinnvoller erscheint und dasselbe tut, ohne teils eigensinnige Nebeneffekte. Bezüglich des unzureichenden Quotings, könnte die Aussage kaum wahrer sein. So oft selbst erlebt in der Vergangenheit. Insbesondere im Umgang mit exotischen Datei -und Ordnernamen wird das problematisch, oder wenn einfach nur Leerzeichen darin enthalten sind.

Benutzeravatar
heisenberg
Beiträge: 3559
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von heisenberg » 18.01.2017 20:08:36

weedy hat geschrieben:

Code: Alles auswählen

+$ testvariable=foo
+$ if echo "$testvariable" | grep -q "foo"; then
+>  echo fooo
+> fi
fooo
Rein um zu verstehen, was abläuft: Ja.

Zum verwenden: Nein, da unnötig ineffezient.

Die oben vorgestellten Methoden sind besser.

Das Konstrukt echo irgendwas | Kommando mag man in der Shell so benutzen und da ist auch nix dabei. Doch im Skript würde ich da immer auf den zusätzlichen unnötigen Befehl verzichten und statt dessen die Variante Kommando <<<"irgendwas" bevorzugen.

Google useless use of cat / useless use of echo
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von Meillo » 19.01.2017 00:02:46

heisenberg hat geschrieben: Das Konstrukt echo irgendwas | Kommando mag man in der Shell so benutzen und da ist auch nix dabei. Doch im Skript würde ich da immer auf den zusätzlichen unnötigen Befehl verzichten und statt dessen die Variante Kommando <<<"irgendwas" bevorzugen.
... aber mit /bin/bash im Shebang.

Oder du verwendest case, dann geht's auch portabel und ohne zusaetzliche Prozesse.

Google useless use of cat / useless use of echo
Da gibt es solche und andere Meinungen: http://marmaro.de/docs/chaosseminar/on-performance/
Use ed once in a while!

ren22

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von ren22 » 19.01.2017 19:53:22

heisenberg hat geschrieben:Subshell ist nicht nötig und gar ganz übel.
Warum ist subshell ganz übel, verstehe ich nicht so ganz wie Du das meinst mit "ganz übel"

Benutzeravatar
heisenberg
Beiträge: 3559
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von heisenberg » 19.01.2017 20:42:43

Eine Subshell oder ein externer Befehl - z. B. grep bedeutet, dass die laufende Prozessumgebung(Speicher) einmal komplett im RAM kopiert wird und anschliessend der gewünschte Befehl, z. B. grep oder eben wieder die Shell in die Kopie des Speichersegment geschrieben und dann ausgeführt. Im Vergleich dazu laufen Funktionen der Shell in der aktuellen Umgebung mit dem aktuell geladenen Programm(=Shell)

Eine Pipe aus 8 externen Befehlen erzeugt also 8 zusätzliche Prozesse.

Das kann bei großen Shellprogrammen, die ineffizient Programmiert wurden, tausende solcher Prozesserzeugungen verursachen und das Programm um Welten langsamer und Ressourcenhungriger werden lassen.

NACHTRAG

Deutlich hat man das beim letzten Scriptcontest gesehen: Die Anfangsvariante hat ca. 7 Sekunden gebraucht. Nachdem die Prozesserzeugungen wegoptimiert waren noch Null-komma-irgendwas.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Benutzeravatar
Meillo
Moderator
Beiträge: 8818
Registriert: 21.06.2005 14:55:06
Wohnort: Balmora
Kontaktdaten:

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von Meillo » 19.01.2017 22:14:08

heisenberg hat geschrieben:Eine Subshell oder ein externer Befehl - z. B. grep bedeutet, dass die laufende Prozessumgebung(Speicher) einmal komplett im RAM kopiert wird [...]
In Zeiten vor COW war das mal so. Heute wird nur kopiert was noetig ist.

Natuerlich ist das mehr Aufwand, aber das ist halt die eine Seite eines Kompromisses auf dessen anderer Seite die Einfachheit (und damit Verstaendlichkeit und Fehlerminimierung) der Software und dessen groessere Flexibilitaet durch orthogonale Kombinierbarkeit stehen. Eine klare Antwort, wie man diesen Kompromiss entscheiden soll, gibt es IMO nicht -- mal ist der eine Aspekt wichtiger, mal der andere.
Use ed once in a while!

Benutzeravatar
heisenberg
Beiträge: 3559
Registriert: 04.06.2015 01:17:27
Lizenz eigener Beiträge: MIT Lizenz

Re: Bash IF Abfrage, Befehl, Subshell ?

Beitrag von heisenberg » 19.01.2017 22:57:48

Natürlich ist das mehr Aufwand, aber das ist halt die eine Seite eines Kompromisses auf dessen anderer Seite die Einfachheit (und damit Verstaendlichkeit und Fehlerminimierung) der Software und dessen groessere Flexibilitaet durch orthogonale Kombinierbarkeit stehen. Eine klare Antwort, wie man diesen Kompromiss entscheiden soll, gibt es IMO nicht -- mal ist der eine Aspekt wichtiger, mal der andere.
Ohne Anspruch auf die einzig richtige Lösung haben zu meinen, kann ich keinen Verständnisvorteil von einer Pipechain im Vergleich zu einer Folge von Einzelbefehlen/-funktionen sehen. In der persönlichen Anwendungserfahrung ist das Pipe-Prinzip eher so: Ich papp' solang' was hintendran, bis es geht. Das läuft darauf hinaus, dass der Prozess eher unnötig komplex wird, also das Gegenteil von einem Verständnisvorteil.

Aber vielleicht machen andere das ja anders.

Ansonsten zeigen die vorliegenden Trivialbeispiele IMHO auch eher eine größere Komplexität und schlechtere Lesbarkeit als die logischen Ausdrücke.

Aber das mag jeder für sich selbst entscheiden.

Wartbarkeit und Effizienz sind IMHO zwei elementare Schwerpunkte. Ich sehe nicht, dass sich die beiden zwangsläufig ausschließen. Eher das Gegenteil: Effiziente Programme können sehr simpel sein und deswegen einfach zu verstehen. Im Gegensatz zur einfachen Lesbarkeit erfordern einfache und effiziente Lösungen mitunter ein erhebliches Maß an Hirnschmalz.

Das alles seine Vor- und Nachteile hat und seinen Einsatzzweck ist klar.

Ich denke auch dass es eine Frage der Gewohnheit ist. Bei mir weicht die Gewohnheit des hintereinanderpappens zunehmend den gelernten und geübten von mir erwähnten Methoden. Zumindest sobald dieser Code es Wert ist in eine Datei geschrieben zu werden.
Jede Rohheit hat ihren Ursprung in einer Schwäche.

Antworten