Macro in Bash

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Macro in Bash

Beitrag von Lohengrin » 19.11.2018 17:13:52

Es gibt Programmiersprachen, wo, wenn ameise=biene und biene=summ gesetzt wurde, aus &&ameise erst &biene und dann summ wird.
Bei Bash funktioniert cebra=${$ameise} nicht. Es funktioniert aber cebra=$(eval echo '$'$ameise). Geht das auch einfacher?
Harry, hol schon mal das Rasiermesser!

Benutzeravatar
smutbert
Moderator
Beiträge: 8315
Registriert: 24.07.2011 13:27:39
Wohnort: Graz

Re: Macro in Bash

Beitrag von smutbert » 19.11.2018 17:24:08

Obwohl die Shell nicht meine Stärke ist, weiß ich das zufällig

Code: Alles auswählen

cebra=${!ameise}

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Macro in Bash

Beitrag von Lohengrin » 19.11.2018 18:06:18

smutbert hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 17:24:08
Obwohl die Shell nicht meine Stärke ist, weiß ich das zufällig

Code: Alles auswählen

cebra=${!ameise}
Sehr schön. Wie so oft. Jetzt, wo ich weiß, wie es geht, finde ich es auch in man bash.

Und noch einen Schritt weiter?
man bash sagt it introduces a level of variable indirection. Da solle es mehrere Level geben.
ameise=biene ; biene=summ ; summ=patsch
cebra=${!!ameise} geht nicht. Und cebra=${!${ameise}} auch nicht.
Harry, hol schon mal das Rasiermesser!

r4pt0r
Beiträge: 1237
Registriert: 30.04.2007 13:32:44
Lizenz eigener Beiträge: MIT Lizenz

Re: Macro in Bash

Beitrag von r4pt0r » 19.11.2018 18:27:41

Um die geistige Gesundheit derer zu wahren, die sorchen code später evtl noch lesen und verstehen müssen (also auch du selbst!), sollte man wenn irgend möglich variable indirection innerhalb des codes vermeiden!
(Und für höhere portabilität kein bash sondern bourne shell verwenden...)

Besser da wesentlich offensichtlicher:

Code: Alles auswählen

% sh
$ ameise=$biene
$ biene=summ
$ echo $ameise
summ
Da variablen i.d.r. am Anfang gesetzt werden ist so direkt ersichtlich was passiert, nicht erst wenn man ggf mehrere hundert Zeilen weiter unten den entsprechenden codefetzen findet der die variable in eine weitere variable auflöst.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Macro in Bash

Beitrag von RobertDebiannutzer » 19.11.2018 19:13:44

Funktionen gibt's ja auch noch...

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Macro in Bash

Beitrag von Lohengrin » 19.11.2018 19:16:16

r4pt0r hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 18:27:41
(Und für höhere portabilität kein bash sondern bourne shell verwenden...)
Wenn es in Bourne läuft, aber nicht in Bash ist es höhere Portabilität als umgekehrt?
r4pt0r hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 18:27:41
Besser da wesentlich offensichtlicher:

Code: Alles auswählen

% sh
$ ameise=$biene
$ biene=summ
$ echo $ameise
summ
Interessant! Das hätte ich nicht erwartet. Bei Bash heißt das declare -n ameise=biene.
Wie macht man denn in Bourne zwischen=$x ; x=$y ; y=$zwischen ?
r4pt0r hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 18:27:41
Da variablen i.d.r. am Anfang gesetzt werden ist so direkt ersichtlich was passiert, nicht erst wenn man ggf mehrere hundert Zeilen weiter unten den entsprechenden codefetzen findet der die variable in eine weitere variable auflöst.
Sehe ich auch so. Ich kenne es besonders von Funktionen. Da benutze ich mittendrin eine Variable, die ich vorher nicht local gesetzt habe, und wundere mich über den Effekt.
Harry, hol schon mal das Rasiermesser!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Macro in Bash

Beitrag von RobertDebiannutzer » 19.11.2018 21:09:55

Lohengrin hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 19:16:16
Ich kenne es besonders von Funktionen. Da benutze ich mittendrin eine Variable, die ich vorher nicht local gesetzt habe, und wundere mich über den Effekt.
Beziehst Du Dich auf meinen Post? Ich verstehe nicht ganz, was Du meinst. Local scopes oder so (wie in Perl oder C z.B.) gibt es AFAIK nicht in bash, außer du landest aus Versehen in einer Subshell (wie es bspw. bei der Konstruktion "cat irgendwas | while read line; do if condition; then var="$line"; fi; done" der Fall ist, wo Du Dich dann nachher wunderst, dass var leer ist...).
Ich hatte mich hieran orientiert:
r4pt0r hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 18:27:41

Code: Alles auswählen

% sh
$ ameise=$biene
$ biene=summ
$ echo $ameise
summ
Das kann man eben auch so machen:

Code: Alles auswählen

$ ameise () { echo $biene; }
$ biene=summ
$ ameise
summ
oder

Code: Alles auswählen

$ ameise () { summ; }
$ summ () { echo patsch; }
$ cebra=$(ameise)
$ echo $cebra
patsch
Ob sowas in der Art jetzt praktisch ist oder nicht, hängt ja auch vom Einzelfall ab. Wollte nur mal auf die Möglichkeit hingewiesen haben...

tobo
Beiträge: 1964
Registriert: 10.12.2008 10:51:41

Re: Macro in Bash

Beitrag von tobo » 19.11.2018 21:19:14

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 21:09:55
Lohengrin hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 19:16:16
Ich kenne es besonders von Funktionen. Da benutze ich mittendrin eine Variable, die ich vorher nicht local gesetzt habe, und wundere mich über den Effekt.
Beziehst Du Dich auf meinen Post? Ich verstehe nicht ganz, was Du meinst. Local scopes oder so (wie in Perl oder C z.B.) gibt es AFAIK nicht in bash,
Dann probiere mal in deiner bash das:

Code: Alles auswählen

$ help local

Benutzeravatar
MartinV
Beiträge: 788
Registriert: 31.07.2015 19:38:52
Wohnort: Hyperion
Kontaktdaten:

Re: Macro in Bash

Beitrag von MartinV » 19.11.2018 21:37:03

Code: Alles auswählen

% sh
$ ameise=$biene
$ biene=summ
$ echo $ameise
summ
Schreibt Ihr auch Code, oder macht Ihr nur Theorie? :P
Dieser Schnipsel wurde jetzt schon mehrfach zitiert und ist immer noch falsch. :roll:
Die Vernunft kann einem schon leidtun. Sie verliert eigentlich immer.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Macro in Bash

Beitrag von RobertDebiannutzer » 19.11.2018 22:16:50

tobo hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 21:19:14
Dann probiere mal in deiner bash das:

Code: Alles auswählen

$ help local
Danke, aber ich meinte default. Also per default sind alle Variablen in C nur für die Funktion gültig, in der sie deklariert wurden. Und das ist bei bash nicht so.

@MartinV: Ups, ich hatte nur auf die Erklärung von @Lohengrin geachtet und gar nicht richtig auf den Code von @r4pt0r...

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Macro in Bash

Beitrag von Lohengrin » 20.11.2018 01:09:57

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 21:09:55
Ich verstehe nicht ganz, was Du meinst. Local scopes oder so (wie in Perl oder C z.B.) gibt es AFAIK nicht in bash, außer du landest aus Versehen in einer Subshell (wie es bspw. bei der Konstruktion "cat irgendwas | while read line; do if condition; then var="$line"; fi; done" der Fall ist, wo Du Dich dann nachher wunderst, dass var leer ist...).
Ja und nein.
Das mit den Scopes ist anders. Eine neu aufgerufene Shell hat ihre eigenen Variablen. Man kann Variablen übergeben, indem man es mit foo=23 ./test.sh aufruft, oder indem man vorher mit mit export foo sagt, dass foo exportiert werden soll. Dann gibt es in test.sh die Variable foo. Aber das ist eine lokale Variable. Das foo in test.sh und das foo im aufrufenden Script sind verschieden. Bei Subshells ist das genauso.
Innerhalb eines Scripts sind alle Variablen global, außer sie sind in der Funktion mit local foo auf local gesetzt. Wenn man vergisst, eine Variable, die man in einer Funktion benutzt, lokal zu machen, dann ist sie global. Das ist ärgerlich, wenn diese Variable x heißt. Man ruft eine Funktion auf, und danach steht in x etwas anderes. Der Fehler fällt erst später auf, und man fragt sich, woher der falsche Wert in x kommt.
Diese globalen Variablen sind praktisch, wenn die Funktion etwas zurückgeben soll. In C würde man &foo übergeben. Aber in Bash geht das nicht. Außer mit globalen Variablen kann man nur den Rückbagewert mit return setzen, oder etwas in einen Kanal schieben, üblicherweise in STDOUT. Das kann dann mit x=$(funktion) eingefangen werden.
Harry, hol schon mal das Rasiermesser!

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Macro in Bash

Beitrag von RobertDebiannutzer » 20.11.2018 09:53:21

Ja, die Möglichkeit, Variablen in Bash nur local zu deklarieren, nutze ich bisher viel zu wenig (meine bash-Scripte sind aber meist auch nur bis 200 Zeilen lang). Aber manchmal ist es ja auch egal, so wie z.B. bei einer Wegwerf-Variable für einen for-loop (solange der nicht nested ist natürlich).
Dann hat man z.B. "for i in $parts; do ..." und kann später natürlich wieder $i benutzen: "for i in {0..99}; do ..."
Übrigens gelten local deklarierte Variablen in bash auch für Funktionen, die innerhalb der betreffenden Funktion aufgerufen werden - s. z.B. https://www.tldp.org/LDP/abs/html/localvar.html (Note [1]) oder "help local" (wie von @tobo vorgeschlagen):

Code: Alles auswählen

    Local variables can only be used within a function; they are visible
    only to the function where they are defined and its children.
Was übrigens auch noch schick ist (je nach Anwendungsfall eben), ist ein associative array:

Code: Alles auswählen

$ summ=patsch
$ declare -A cebra
$ cebra=([ameise]="$summ")
$ echo "${cebra[ameise]}"
patsch
Dann kannst Du auch noch mit Fliegen hantieren:

Code: Alles auswählen

$ cebra+=([fliege]="$summ")
$ echo "${cebra[fliege]}"
patsch
$ echo "${cebra[@]}"
patsch patsch
$ echo "${!cebra[@]}"
ameise fliege
Edit: Du kannst natürlich auch eine Variable als index für den associative array nutzen...
also so z.B.

Code: Alles auswählen

$ declare -A cebra
$ summ=patsch
$ viech=biene
$ cebra=(["$viech"]="$summ")
$ echo "${cebra[biene]}"
patsch

r4pt0r
Beiträge: 1237
Registriert: 30.04.2007 13:32:44
Lizenz eigener Beiträge: MIT Lizenz

Re: Macro in Bash

Beitrag von r4pt0r » 20.11.2018 13:14:41

Lohengrin hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 19:16:16
r4pt0r hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 18:27:41
(Und für höhere portabilität kein bash sondern bourne shell verwenden...)
Wenn es in Bourne läuft, aber nicht in Bash ist es höhere Portabilität als umgekehrt?
Die bourne shell (sh) ist auf _allen_ UNIX (Solaris/Illumos, BSD sowie kommerzielle UNIX wie HP/UX etc.) und UNIX-ähnlichen (Linux) Systemen im base system verfügbar, i.d.r. statisch gelinkt und oft sogar als default-shell. Bash ist eigentlich nur unter Linux bei "den meisten" Distributionen per default installiert.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Macro in Bash

Beitrag von RobertDebiannutzer » 20.11.2018 13:22:49

Da möchte ich gerne noch auf etwas verweisen, was mir @owl102 einmal erklärt hat:
owl102 hat geschrieben: Das Problem bei POSIX ist, daß es keine Shell gibt, die nur POSIX kann. Unter Debian ist zum Beispiel die /bin/sh in Wirklichkeit die dash (Beweis: "ls -l /bin/sh"), die neben POSIX auch ein bischen mehr kann. Unter Fedora/RHEL ist übrigens /bin/sh die bash, die ja auch neben POSIX ein bischen mehr kann. Unter RHEL könnte man also "#!/bin/sh" in die erste Zeile schreiben und reichlich bash-Code produzieren, der auf RHEL problemlos funktioniert, aber unter Debian nicht.

Nur weil es funktioniert, heißt das folglich nicht, daß es POSIX ist, und schon gar nicht, daß es auch mit anderen POSIX-kompatiblen Shells funktioniert. Man muß wissen, was der POSIX-Standard hergibt (und was nicht).
Quelle: viewtopic.php?f=34&t=168091&sid=ccb65c2 ... 3#p1158621

Benutzeravatar
MSfree
Beiträge: 10686
Registriert: 25.09.2007 19:59:30

Re: Macro in Bash

Beitrag von MSfree » 20.11.2018 13:40:56

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
20.11.2018 13:22:49
Da möchte ich gerne noch auf etwas verweisen, was mir @owl102 einmal erklärt hat:
owl102 hat geschrieben: Das Problem bei POSIX ist, daß es keine Shell gibt, die nur POSIX kann. Unter Debian ist zum Beispiel die /bin/sh in Wirklichkeit die dash (Beweis: "ls -l /bin/sh"), ...
Das ist zunächst richtig. Allerdings bekommt die dash (oder auch die bash) über den ersten Aufrufparameter (hier /bin/sh) mit, daß sie sich wie eine sh verhalten soll. Wenn du damit versuchst, bash-Syntax auszuführen, sollte das eigentlich mit Syntaxfehlern fehlschlagen.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Macro in Bash

Beitrag von RobertDebiannutzer » 20.11.2018 14:07:55

Also folgendes Script funktioniert, wenn ich es mit "bash ./script.sh" starte. (Einfach nur ausführen geht ja nicht, weil dann kommt ja dash zum Zuge und versteht natürlich die enthaltenen bash-Spezialitäten nicht.) Auch "bash --posix ./script.sh" funktioniert seltsamerweise... Letzteres verstehe ich überhaupt nicht, denn dash z.B. kann mit "[[", associative arrays, "for ((..." und "if ((..." doch gar nix anfangen...

Code: Alles auswählen

#!/bin/sh

if [[ -d "$HOME" ]]; then
	declare -A num
	num=([eins]="one" [zwei]="two" [drei]="three")
	for ((i=0; i<3; i++)); do
		if ((i == 0)); then
			echo "${num[eins]}"
		elif ((i == 1)); then
			echo "${num[zwei]}"
		elif ((i == 2)); then
			echo "${num[drei]}"
		fi
	done
fi

tobo
Beiträge: 1964
Registriert: 10.12.2008 10:51:41

Re: Macro in Bash

Beitrag von tobo » 20.11.2018 14:57:39

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
20.11.2018 14:07:55
Auch "bash --posix ./script.sh" funktioniert seltsamerweise... Letzteres verstehe ich überhaupt nicht, denn dash z.B. kann mit "[[", associative arrays, "for ((..." und "if ((..." doch gar nix anfangen...
Das ist nur Posix ähnlich - da sind noch genügend Bashism enthalten, die man in Skripten vermeiden sollte.
Verlinkt von man bash zum Parameter posix:
https://tiswww.case.edu/php/chet/bash/POSIX

r4pt0r
Beiträge: 1237
Registriert: 30.04.2007 13:32:44
Lizenz eigener Beiträge: MIT Lizenz

Re: Macro in Bash

Beitrag von r4pt0r » 20.11.2018 15:13:51

Wenn das script mit '#!/bin/sh' beginnt _muss_ es mit sh (bourne/posix shell oder eben dash im "sh-mode") ausgeführt werden. Alles andere wäre kein korrektes Verhalten, d.h. ein bug.
KA was bash mit einem /bin/sh script anstellt; aber 'bash script.sh' sieht in diesem Kontext irgendwie komplett verkehrt aus... bash sollte nur verwendet werden wenn es auch wirklich ein bash-script ist ('#!/bin/bash').

i.e.: wenn die entsprechende shell installiert ist (bourne shell / sh wie gesagt überall verfügbar), und die erste Zeile ein valides shebang enthält (#!/bin/sh), *muss* auch automatisch die entsprechende shell beim ausführen per "./script" verwendet werden.

Etliche tools (bzw meistens wrapper) in /usr/bin sind einfache shellscripte bzw man kann auch problemlos eigene scripte dort unterbringen (bzw korrekterweise eigentlich in /usr/local/bin), diese werden dann auch "direkt" aufgerufen und anhand des shebang die korrekte shell zum ausführen gestartet. Wir sind hier ja nicht bei Windows, das bis heute nur nach Dateiendungen schaut und die Hufe hochreißt wenn diese falsch ist :roll:

tobo
Beiträge: 1964
Registriert: 10.12.2008 10:51:41

Re: Macro in Bash

Beitrag von tobo » 20.11.2018 15:30:56

Mit einer ersten Zeile "#!/bin/sh" im Skript, wird die Shell als Interpreter aufgerufen, die unter /bin/sh hinterlegt ist, sofern das Skript als ausführbare Datei gestartet wird (./script.sh). Das kann genauso die bash oder fish sein. Wird das Skript direkt am Interpreter (z.B. bash script.sh) gestartet, dann dann hat diese erste Zeile (Shebang) überhaupt keine Bedeutung.

RobertDebiannutzer
Beiträge: 385
Registriert: 16.06.2017 09:52:36

Re: Macro in Bash

Beitrag von RobertDebiannutzer » 20.11.2018 15:47:51

ok, habe nun den symbolic link von /bin/sh geändert, zeigt nun auf nicht mehr auf /bin/dash, sondern auf /bin/bash.
Führe ich nun die Datei einfach mit "./script.sh" aus, wird sie nach wie vor korrekt interpretiert.
Somit ist m.E. widerlegt, dass
MSfree hat geschrieben: ↑ zum Beitrag ↑
20.11.2018 13:40:56
Allerdings bekommt die dash (oder auch die bash) über den ersten Aufrufparameter (hier /bin/sh) mit, daß sie sich wie eine sh verhalten soll.
Und obwohl in dem Link aus @tobos Beitrag steht...
When invoked as 'sh', Bash enters POSIX mode after reading the startup
files.
ist eben - wie @tobo schon sagte - der POSIX-Modus von bash nicht gleich das POSIX, was man vielleicht denkt...

Und das liegt möglicherweise auch daran, dass es - wie @owl102 sagte - keine "POSIX-Shell", nicht *die* "sh", gibt.

Am nahesten an das, was man sich unter "Posix-Kompatibilität" vorstellt, kommt da wohl dash - aus der manpage von dash:
dash is the standard command interpreter for the system. The current version of dash is in the process of being changed to conform with the POSIX 1003.2 and 1003.2a specifications for the shell. This version has many features
which make it appear similar in some respects to the Korn shell, but it is not a Korn shell clone (see ksh(1)). Only features designated by POSIX, plus a few Berkeley extensions, are being incorporated into this shell.

tobo
Beiträge: 1964
Registriert: 10.12.2008 10:51:41

Re: Macro in Bash

Beitrag von tobo » 20.11.2018 17:31:23

RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
20.11.2018 15:47:51
ok, habe nun den symbolic link von /bin/sh geändert, zeigt nun auf nicht mehr auf /bin/dash, sondern auf /bin/bash.
Führe ich nun die Datei einfach mit "./script.sh" aus, wird sie nach wie vor korrekt interpretiert.
Somit ist m.E. widerlegt, dass
MSfree hat geschrieben: ↑ zum Beitrag ↑
20.11.2018 13:40:56
Allerdings bekommt die dash (oder auch die bash) über den ersten Aufrufparameter (hier /bin/sh) mit, daß sie sich wie eine sh verhalten soll.
Und obwohl in dem Link aus @tobos Beitrag steht...
When invoked as 'sh', Bash enters POSIX mode after reading the startup
files.
Was in deinem Skript entspricht denn einem Punkt der Liste aus meinem Link und dürfte daher nicht funktionieren?
Teste:

Code: Alles auswählen

$ bash -c 'cat <(date)'
$ bash --posix -c 'cat <(date)'
Und dann schreibe mal "cat <(date)" als Zeile in dein Skript, aufgerufen über den umgebogenen Link. Stimmt schon, was da in der manpage steht. Die Einschränkung ist aber halt nicht Bash-Syntax, sondern das, was oben im Link gelistet ist.

owl102

Re: Macro in Bash

Beitrag von owl102 » 20.11.2018 18:53:02

Es ist doch ganz einfach:

- Benötigt man keine Kompatiblität zu anderen Shells außer der bash, ist es sinnvoll, bash-Skripte zu schreiben, die Features der bash nutzen. Sie machen den Code einfacher, lesbarer, robuster und wartbarer.

- Benötigt man Kompatiblität zu anderen Shells außer der bash, ist es sinnvoll, POSIX-Scripte zu schreiben.

Egal wie man sich entscheidet, auf beiden Seiten gewinnt man etwas und verliert etwas. Eine Entscheidung muß daher IMHO individuell gefällt werden.

Ich persönlich habe zum Beispiel nicht das Problem, daß irgendeines meiner Skripte auch plötzlich unter einem Illumos laufen können muß, wo keine bash installiert ist, ich keine root-Rechte habe (und sie somit auch nicht selber nachinstallieren kann), und der Admin auch keine bash installieren mag.

Aber eigentlich betrifft das Problem alle Programmiersprachen, die sich im Laufe der Jahre weiterentwickeln, C, C++, Java, Perl, Python, ... Welche Version des Standards benutzt man hier?

Im Falle des POSIX-Standards hat man sogar noch ein weiteres Problem: Der POSIX-Standard ist an vielen Stellen schwammig. Selbst wenn man "#!/bin/sh" schreibt und keine Bashisms verwendet, kann es sehr gut sein, daß das Skript in einer anderen Umgebung/Shell nicht wie erwartet funktioniert. Beispiel "echo": Es ist lediglich spezifiziert, daß es Zeichenketten + Zeichenumbruch ausgibt. Verhalten bei Sequenzen mit Backslash am Anfang, wie z.B. "\t"? AFAIK nicht durch POSIX gedeckt, kann so oder so sein. [1] Schalter "-n" vorhanden? AFAIK nicht durch POSIX gedeckt. (Deswegen hier am besten immer printf statt echo verwenden.) Wird bei "xxx | ... <Schleife>" intern eine Subshell gestartet oder nicht, d.h. sind dort gesetzte Variablen auch am Ende der Schleife noch vorhanden? Nach meinem Kenntnisstand läßt POSIX dies offen, d.h. das kann jede Shell so machen wie sie mag. [2] Und so weiter... Bei bash hingegen hat man nur bei anderen Versionen der bash ggf. ein anderes Verhalten, und diese Dinge sind sowohl übersichtlich als auch konkret dokumentiert.

Und dann ist POSIX auch nicht gleich POSIX, auch hier gibt es unterschiedliche Versionen des Standards. Wenn man sich für POSIX entscheidet, welche Version des Standards nimmt man?

[1] Quelle: http://mywiki.wooledge.org/Bashism
[2] Quelle: http://mywiki.wooledge.org/BashFAQ/024

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Macro in Bash

Beitrag von Lohengrin » 20.11.2018 22:41:37

Faszinierend!
Ich habe bei meiner Programmiererei in Bash nie so etwas wie ${!ameise} gebraucht, wusste nur, dass das woanders geht, und wollte wissen, wie es geht.
Und nun stelle ich fest, dass Posix sehr unkonkret ist. Ich habe den Eindruck, dass die große Mehrheit der unixartigen Betriebssysteme GNU/Linux sind, und dass es auf denen Bash gibt, aber kein Bourne. Da fällt mir die Auswahl bzgl Kompatibilität leicht.
Harry, hol schon mal das Rasiermesser!

raa
Beiträge: 411
Registriert: 19.12.2013 10:16:19

Re: Macro in Bash

Beitrag von raa » 21.11.2018 00:42:37

Mal ehrlich: Welcher Kaputte außer mir programmiert denn noch auf Shell-Ebene? :wink:
RobertDebiannutzer hat geschrieben: ↑ zum Beitrag ↑
19.11.2018 19:13:44
Funktionen gibt's ja auch noch...
Gott sei Dank auch. Irgendwann hab' ich also mal angefangen, die kryptischen Befehle (die ich mir nie im Leben merken kann und will), als Funktionen in private "Libraries" zu verpacken. Es ist wohl ein Unterschied, ob man jedesmal sowas konstruieren muss:

Code: Alles auswählen

echo "$str" | sed -e "s/"$strLeftMarg"[^<>]*"$strRightMarg"/"$strSub"/g; /^[ ]*$/d" 
Oder einfach aus dem Katalog kopiert:

Code: Alles auswählen

# Jeden Teilstring von $strLeftMarg bis $strRightMarg ersetzen
strRep=$(replPartStrings "$str" "$strLeftMarg" "$strRightMarg" "$strSub")
(Funzt übrigens sowohl mit Strings als auch mit Dateien, klar.) Damit macht's also richtig Spaß, wenn auch (oder gerade weil) jetzt meine Scripte größtenteils nur noch entfernte Ähnlichkeit mit Shellscripten haben, schon eher nach einer höheren Sprache aussehen. :wink:

Benutzeravatar
Lohengrin
Beiträge: 3227
Registriert: 29.08.2004 00:01:05
Wohnort: Montsalvat

Re: Macro in Bash

Beitrag von Lohengrin » 21.11.2018 01:18:24

raa hat geschrieben: ↑ zum Beitrag ↑
21.11.2018 00:42:37
Irgendwann hab' ich also mal angefangen, die kryptischen Befehle (die ich mir nie im Leben merken kann und will), als Funktionen in private "Libraries" zu verpacken. Es ist wohl ein Unterschied, ob man jedesmal sowas konstruieren muss:

Code: Alles auswählen

echo "$str" | sed -e "s/"$strLeftMarg"[^<>]*"$strRightMarg"/"$strSub"/g; /^[ ]*$/d" 
Die $strLeftMarg, $strRightMarg und $strSub sind nackt. Wenn die Leerzeichen oder Tab drin haben, hast du ein Problem.

Ansonsten richtig so! Jedenfalls in der Theorie.
Wenn ich zwei mal das gleiche Kompliziertere brauche, ist es Zeit für eine Funktion. Dann hat man (so wie jetzt du) nämlich mögliche Fehler an derselben Stelle. Nur wenn ich die beiden zurechtbiegen muss, damit sie dieselbe Funktion benutzen können, kann es sein, dass die Biegerei aufwendiger ist als der Vorteil durch die Funktion.

Leider habe ich das bei meinem letzten Werk verbaselt. Da steht

Code: Alles auswählen

 47      $hash_prog | cut -f1 -d\  | xxd -r -p | base64 -w0 | tr -d '='
159  salzlaenge=$($hash_prog < /dev/null | cut -f1 -d\ | xxd -r -p | wc -c)
167      x=$(head -c $salzlaenge < /dev/urandom | base64 -w0)
Und dann ist mir das auf die Füße gefallen.

Einer mit BSD, der es ausprobiert hat, hat bei seinem base64 die Option -w nicht. der musste dann von base64 -w0 | tr -d '=' umstellen auf base64 | tr -d '=\n'. Der hat den Fehler natürlich nochmal gehabt, nachdem er es schon repariert hatte.
raa hat geschrieben: ↑ zum Beitrag ↑
21.11.2018 00:42:37
Damit macht's also richtig Spaß, wenn auch (oder gerade weil) jetzt meine Scripte größtenteils nur noch entfernte Ähnlichkeit mit Shellscripten haben, schon eher nach einer höheren Sprache aussehen. :wink:
Bei mir ist es umgekehrt.
Ich mag if A ; then B ; else C ; fi nicht. Das ist mir zu hochsprachig. Ich bevorzuge A && B || C. Leider muss ich mir da sicher sein, dass B 0 zurückgibt, sonst muss es A && { B ; true ; } || C heißen, was mir aber immernoch viel besser gefällt als das Hochsprachige. Ist doch schon fast so hübsch wie A?B:C.
Harry, hol schon mal das Rasiermesser!

Antworten