Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. Da wird z.B. eine Textdatei aus dem System geparst und daraufhin bestimmte Variablen und auch Pfade gesetzt. Diese werden dann im weitere Verlauf genutzt und zu verschiedenen Aktivitäten führen. Soweit so normal.
Jetzt ist mein script schon etwas länglich geworden und es droht die Übersicht verloren zu gehen. Also hab ich es in Funktionen aufgeteilt. Damit wird das script aber nicht kürzer. Das ganze möchte ich etwas wartungsfreundlicher und lesbarer gestalten. Ideal wäre ein einem Startscript die Variablen/Pfade zu setzen und dann bestimmte Unterscripts zu starten. Was aber dabei ein Problem zu sein scheint: a) die Variablen vom Startscript übernehmen b) Variablen im Idealfall auch noch von Unterscript zu Unterscript weiterreichen
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus. Ich meine, das nicht mal a) da so ohne weiteres geht. Oder gibt es da Tricks? Ich hab nicht so viel sinnvolles dazu gefunden oder ich hab nicht die richtigen keywords dazu.
Zusatzfrage: Wenn ein Script wie meines gerade aus Funktionen besteht: Am Ende der Funktionsdefinitionen werden die aufgerufen. Kann man z.B. zum Testen, diese Funktionen (aus einer echten) Shell auch einzeln aufrufen? Also nur einzelne Funktionen um das Step by Step zu testen. Wie gesagt, die Pfade/Variablen müssen gesetzt bleiben, sonst ist es sinnlos. Bei läuft dann immer nur das ganze Script... Wenn ich das richtig verstanden hab, kann man nur dann einzelne Funktionen eines scripts aufrufen, wenn es kein "main" gibt, also sozusagen nur Funktionen. Ist das wahr?
Schöne Woche, Arno
Hallo Arno,
Das hängt von deiner verwendeten Shell ab.
In der Bash gibt es das "source"-Kommando dafür. https://devconnected.com/source-command-on-linux-explained/
Viele Grüße, Stefan.
Gesendet: Montag, 01. August 2022 um 17:17 Uhr Von: "Arno" epsi@gmx.de An: flug@lug-freiburg.de Betreff: shell scripte und Funktionen/Gliederung
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. Da wird z.B. eine Textdatei aus dem System geparst und daraufhin bestimmte Variablen und auch Pfade gesetzt. Diese werden dann im weitere Verlauf genutzt und zu verschiedenen Aktivitäten führen. Soweit so normal.
Jetzt ist mein script schon etwas länglich geworden und es droht die Übersicht verloren zu gehen. Also hab ich es in Funktionen aufgeteilt. Damit wird das script aber nicht kürzer. Das ganze möchte ich etwas wartungsfreundlicher und lesbarer gestalten. Ideal wäre ein einem Startscript die Variablen/Pfade zu setzen und dann bestimmte Unterscripts zu starten. Was aber dabei ein Problem zu sein scheint: a) die Variablen vom Startscript übernehmen b) Variablen im Idealfall auch noch von Unterscript zu Unterscript weiterreichen
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus. Ich meine, das nicht mal a) da so ohne weiteres geht. Oder gibt es da Tricks? Ich hab nicht so viel sinnvolles dazu gefunden oder ich hab nicht die richtigen keywords dazu.
Zusatzfrage: Wenn ein Script wie meines gerade aus Funktionen besteht: Am Ende der Funktionsdefinitionen werden die aufgerufen. Kann man z.B. zum Testen, diese Funktionen (aus einer echten) Shell auch einzeln aufrufen? Also nur einzelne Funktionen um das Step by Step zu testen. Wie gesagt, die Pfade/Variablen müssen gesetzt bleiben, sonst ist es sinnlos. Bei läuft dann immer nur das ganze Script... Wenn ich das richtig verstanden hab, kann man nur dann einzelne Funktionen eines scripts aufrufen, wenn es kein "main" gibt, also sozusagen nur Funktionen. Ist das wahr?
Schöne Woche, Arno
Hallo Stefan,
vielen Dank. Es ist tatsächlich nur die sh, nicht mal die bash, schätze aus der Busybox. Ok verstehe, das souce script.sh macht schon was anderes als nur ein ./script.sh. Also sieht so aus als wenn man im Hauptscript script.sh ein source subscript.sh machen kann und dies alle Variablen kennt die auch in script.sh bekannte sind (bis du dem Aufruf schätze ich). Aber Variablen aus dem subscript wieder in script.sh zurück geben?
Mal sehen ob ich morgen Abend. mal zum testen kommen. Gruß, Arno
Am 01.08.22 um 23:16 schrieb Stefan Ziegler:
Hallo Arno,
Das hängt von deiner verwendeten Shell ab.
In der Bash gibt es das "source"-Kommando dafür. https://devconnected.com/source-command-on-linux-explained/
Viele Grüße, Stefan.
Gesendet: Montag, 01. August 2022 um 17:17 Uhr Von: "Arno" epsi@gmx.de An: flug@lug-freiburg.de Betreff: shell scripte und Funktionen/Gliederung
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. Da wird z.B. eine Textdatei aus dem System geparst und daraufhin bestimmte Variablen und auch Pfade gesetzt. Diese werden dann im weitere Verlauf genutzt und zu verschiedenen Aktivitäten führen. Soweit so normal.
Jetzt ist mein script schon etwas länglich geworden und es droht die Übersicht verloren zu gehen. Also hab ich es in Funktionen aufgeteilt. Damit wird das script aber nicht kürzer. Das ganze möchte ich etwas wartungsfreundlicher und lesbarer gestalten. Ideal wäre ein einem Startscript die Variablen/Pfade zu setzen und dann bestimmte Unterscripts zu starten. Was aber dabei ein Problem zu sein scheint: a) die Variablen vom Startscript übernehmen b) Variablen im Idealfall auch noch von Unterscript zu Unterscript weiterreichen
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus. Ich meine, das nicht mal a) da so ohne weiteres geht. Oder gibt es da Tricks? Ich hab nicht so viel sinnvolles dazu gefunden oder ich hab nicht die richtigen keywords dazu.
Zusatzfrage: Wenn ein Script wie meines gerade aus Funktionen besteht: Am Ende der Funktionsdefinitionen werden die aufgerufen. Kann man z.B. zum Testen, diese Funktionen (aus einer echten) Shell auch einzeln aufrufen? Also nur einzelne Funktionen um das Step by Step zu testen. Wie gesagt, die Pfade/Variablen müssen gesetzt bleiben, sonst ist es sinnlos. Bei läuft dann immer nur das ganze Script... Wenn ich das richtig verstanden hab, kann man nur dann einzelne Funktionen eines scripts aufrufen, wenn es kein "main" gibt, also sozusagen nur Funktionen. Ist das wahr?
Schöne Woche, Arno
On Mon, Aug 01, 2022 at 05:17:25PM +0200, Arno wrote:
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. [...] Soweit so normal.
Jetzt ist mein script schon etwas länglich geworden und es droht die Übersicht verloren zu gehen. Also hab ich es in Funktionen aufgeteilt. Damit wird das script aber nicht kürzer. Das ganze möchte ich etwas wartungsfreundlicher und lesbarer gestalten. Ideal wäre ein einem Startscript die Variablen/Pfade zu setzen und dann bestimmte Unterscripts zu starten. Was aber dabei ein Problem zu sein scheint: a) die Variablen vom Startscript übernehmen b) Variablen im Idealfall auch noch von Unterscript zu Unterscript weiterreichen
Die Frage ist ziemlich allgemein gestellt, deshalb kann nur eine ziemlich allgemeine Antwort gegeben werden.
Was an der Shell besonders ist (und heute eher ungewöhnlich, und ungewohnt) ist, dass die "Variablen" einen dynamischen Scope haben, d.h., wenn ich eine in einem Stück Shell setze, dann ist sie in allen Stücken, die von dort aus aufgerufen werden auch "sichtbar" (wenn das Aufrufen nicht als (shell-) Funktion passiert, sondern durch "Aurufen" einer anderen Datai (Subshell), dann muss die Variable EXPORTiert werden).
Eine andere Ungewöhnlichkeit ist das Textersetzungsmodell: eine Zeile wird erst nach bestimmten Regeln transformiert ($variable wird durch ihr Wert ersetzt, $(ausdruck) auch, etc.) und dann erst interpretiert.
Diese zwei Dinge zu managen führt zu einem etwas anderen Stil in der Programm"architektur".
So. Genug herumgeschwafelt ;-)
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus. Ich meine, das nicht mal a) da so ohne weiteres geht. Oder gibt es da Tricks? Ich hab nicht so viel sinnvolles dazu gefunden oder ich hab nicht die richtigen keywords dazu.
Das ist alles halb so wild. Shell ist shell. Du musst wissen, mit welcher Du es zu tun hast (ist es die bash? ist es ihre kleine Schwester) und Du musst berücksichtigen, mit welcher Umgebung Du es zu tun hast (ist $PATH so wie Du sie erwartest? Musst Du ggf. "/bin/rm" statt nur "rm" sagen? Plane etwas Zeit ein fürs Debuggen).
Zusatzfrage: Wenn ein Script wie meines gerade aus Funktionen besteht: Am Ende der Funktionsdefinitionen werden die aufgerufen. Kann man z.B. zum Testen, diese Funktionen (aus einer echten) Shell auch einzeln aufrufen?
How do the masters do it?
Einen netten Ansatz findest Du bei den alten sysvinit-Skripten. Die ersten zwei Zeilen (abgesehen von Kommentaren) in einem (Quizfrage: welches?) von meinen sehen so aus:
[ -r /usr/share/postgresql-common/init.d-functions ] || exit 0 . /usr/share/postgresql-common/init.d-functions
Es wird eine Datei "gesourct", in der irgendwelche nützliche Funktionen definiert werden. Das würde ich mal das "library"-Pattern nennen.
Also nur einzelne Funktionen um das Step by Step zu testen. Wie gesagt, die Pfade/Variablen müssen gesetzt bleiben, sonst ist es sinnlos.
Was auch immer Du damit meinst. Das muss konkreter werden. Wenn ich eine Variable in einer Funktion setze, dann ist dieser Zustand im die Funktion einschliessenden Skript sichtbar. Nicht jedoch, wenn ich sie in einem "Unterskript" setze.
Bei läuft dann immer nur das ganze Script... Wenn ich das richtig verstanden hab, kann man nur dann einzelne Funktionen eines scripts aufrufen, wenn es kein "main" gibt, also sozusagen nur Funktionen. Ist das wahr?
Ich weiss nicht genau, wie ich die Aussage im Kontext einer Shell verstehen soll. Vermutlich nicht. Wer oder was ist "main"?
Nehmen wir an, ich habe ein Skript, nennen wir es "muuh":
#!/bin/bash echo "Guten Morgen"
say-hello () { echo hello }
say-good-bye () { echo good bye }
Und dann "source" ich das Ding in einem anderen:
... . muuh ...
Was passiert ist, dass wenn die Ausführung in meinem Skript an diesen Punkt kommt, "Guten Morgen" ausgegeben wird (wohin immer gerade stdout zeigt) und die zwei Funktionen definiert werden, die ich dann im weiteren Verlauf verwenden kann.
Ein ganz gerader, naiver Interpreter: mach' dies, dann mach' das. Ob die Ausgabe von "Guten Morgen" jetzt erwünscht war oder nicht, das kannst nur Du wissen. Typischerweise wird man so eine Library so bauen, dass sie nur Funktionen definiert, sei es nur darum, nicht den Verstand zu verlieren. Vielleicht meintest Du das mit "main".
Solche allgemeinen Regeln finde ich immer suspekt.
Da gibt es noch ein anderes Muster, das mit den Subcommands (inspiriert durch git). Aber das möge erst mal genügen :)
lg
Am 02.08.22 um 07:15 schrieb tomas@tuxteam.de:
On Mon, Aug 01, 2022 at 05:17:25PM +0200, Arno wrote:
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. [...] Soweit so normal.
Jetzt ist mein script schon etwas länglich geworden und es droht die Übersicht verloren zu gehen. Also hab ich es in Funktionen aufgeteilt. Damit wird das script aber nicht kürzer. Das ganze möchte ich etwas wartungsfreundlicher und lesbarer gestalten. Ideal wäre ein einem Startscript die Variablen/Pfade zu setzen und dann bestimmte Unterscripts zu starten. Was aber dabei ein Problem zu sein scheint: a) die Variablen vom Startscript übernehmen b) Variablen im Idealfall auch noch von Unterscript zu Unterscript weiterreichen
Die Frage ist ziemlich allgemein gestellt, deshalb kann nur eine ziemlich allgemeine Antwort gegeben werden.
Was an der Shell besonders ist (und heute eher ungewöhnlich, und ungewohnt) ist, dass die "Variablen" einen dynamischen Scope haben, d.h., wenn ich eine in einem Stück Shell setze, dann ist sie in allen Stücken, die von dort aus aufgerufen werden auch "sichtbar" (wenn das Aufrufen nicht als (shell-) Funktion passiert, sondern durch "Aurufen" einer anderen Datai (Subshell), dann muss die Variable EXPORTiert werden).
Eine andere Ungewöhnlichkeit ist das Textersetzungsmodell: eine Zeile wird erst nach bestimmten Regeln transformiert ($variable wird durch ihr Wert ersetzt, $(ausdruck) auch, etc.) und dann erst interpretiert.
Diese zwei Dinge zu managen führt zu einem etwas anderen Stil in der Programm"architektur".
So. Genug herumgeschwafelt ;-)
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus. Ich meine, das nicht mal a) da so ohne weiteres geht. Oder gibt es da Tricks? Ich hab nicht so viel sinnvolles dazu gefunden oder ich hab nicht die richtigen keywords dazu.
Das ist alles halb so wild. Shell ist shell. Du musst wissen, mit welcher Du es zu tun hast (ist es die bash? ist es ihre kleine Schwester) und
Ja, es ist nur die /bin/sh
Du musst berücksichtigen, mit welcher Umgebung Du es zu tun hast (ist $PATH so wie Du sie erwartest? Musst Du ggf. "/bin/rm" statt nur "rm" sagen? Plane etwas Zeit ein fürs Debuggen).
Das ist klar, da verwende ich nur absolute Pfade.
Zusatzfrage: Wenn ein Script wie meines gerade aus Funktionen besteht: Am Ende der Funktionsdefinitionen werden die aufgerufen. Kann man z.B. zum Testen, diese Funktionen (aus einer echten) Shell auch einzeln aufrufen?
How do the masters do it?
Einen netten Ansatz findest Du bei den alten sysvinit-Skripten. Die ersten zwei Zeilen (abgesehen von Kommentaren) in einem (Quizfrage: welches?) von meinen sehen so aus:
[ -r /usr/share/postgresql-common/init.d-functions ] || exit 0 . /usr/share/postgresql-common/init.d-functions
Es wird eine Datei "gesourct", in der irgendwelche nützliche Funktionen definiert werden. Das würde ich mal das "library"-Pattern nennen.
Konkret: Wenn value=10 vor dem Aufruf von init.d-functions steht, dann ist value dort bekannt. Aber was wenn ich in init.d-functions value2=20 setze. Kann ich die 20 in dem aufrufenden Vater-Script verwenden?
Also nur einzelne Funktionen um das Step by Step zu testen. Wie gesagt, die Pfade/Variablen müssen gesetzt bleiben, sonst ist es sinnlos.
Was auch immer Du damit meinst. Das muss konkreter werden. Wenn ich eine Variable in einer Funktion setze, dann ist dieser Zustand im die Funktion einschliessenden Skript sichtbar. Nicht jedoch, wenn ich sie in einem "Unterskript" setze.
Bei läuft dann immer nur das ganze Script... Wenn ich das richtig verstanden hab, kann man nur dann einzelne Funktionen eines scripts aufrufen, wenn es kein "main" gibt, also sozusagen nur Funktionen. Ist das wahr?
Ich weiss nicht genau, wie ich die Aussage im Kontext einer Shell verstehen soll. Vermutlich nicht. Wer oder was ist "main"?
Nehmen wir an, ich habe ein Skript, nennen wir es "muuh":
#!/bin/bash echo "Guten Morgen"
say-hello () { echo hello }
say-good-bye () { echo good bye }
Und dann "source" ich das Ding in einem anderen:
... . muuh ...
Ok aber kann ich auch (Syntax frei erfunden) . muh::say-hello() machen und dann wird nur "hello" zurückgebeben. Das meine ich, wenn ich die Funktionen eines Scripts testen will.
Bei mir wäre gegenwärtig das Problem das das muh wohl so aussieht:
#/bin/sh funk1() { echo 1 } funk2() { echo 2 } funk3() { echo 3 } echo Test funk1 echo blabla funk3 funk2
Ich müsste zum Test die unteren 5 Zeilen komplett rausnehmen und source muh.sh funk2
machen um nur funk2 zu testen, richtig?
Was passiert ist, dass wenn die Ausführung in meinem Skript an diesen Punkt kommt, "Guten Morgen" ausgegeben wird (wohin immer gerade stdout zeigt) und die zwei Funktionen definiert werden, die ich dann im weiteren Verlauf verwenden kann.
Immerhin. Also sind die Funktionen auch nach Ausführung noch verfügbar.
Ein ganz gerader, naiver Interpreter: mach' dies, dann mach' das. Ob die Ausgabe von "Guten Morgen" jetzt erwünscht war oder nicht, das kannst nur Du wissen. Typischerweise wird man so eine Library so bauen, dass sie nur Funktionen definiert, sei es nur darum, nicht den Verstand zu verlieren. Vielleicht meintest Du das mit "main".
Solche allgemeinen Regeln finde ich immer suspekt.
Da gibt es noch ein anderes Muster, das mit den Subcommands (inspiriert durch git). Aber das möge erst mal genügen :)
lg
Also vielen Dank für die Mühe, dann werd ich mich mal ans refactoring machen und mit kleinen Demos beginnen.
Viele Grüße, Arno
On Tue, Aug 02, 2022 at 05:51:40PM +0200, Arno wrote:
Am 02.08.22 um 07:15 schrieb tomas@tuxteam.de:
On Mon, Aug 01, 2022 at 05:17:25PM +0200, Arno wrote:
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. [...] Soweit so normal.
[...]
Das ist alles halb so wild. Shell ist shell. Du musst wissen, mit welcher Du es zu tun hast (ist es die bash? ist es ihre kleine Schwester) und
Ja, es ist nur die /bin/sh
"die" /bin/sh gibt es nicht wirklich:
tomas@trotzki:~$ ls -al /bin/sh lrwxrwxrwx 1 root root 4 Dec 10 2020 /bin/sh -> dash
(Wenn Du sagst, dass es bei Dir eine Busybox ist, dann wird's etwas anders sein).
das einzige, was dieser Tage erwartet wird ist, dass sie einigermassen Bourne-kompatibel ist.
Du musst berücksichtigen, mit welcher Umgebung Du es zu tun hast (ist $PATH so wie Du sie erwartest? [...]
Das ist klar, da verwende ich nur absolute Pfade.
Nicht so klar: vielleicht willst Du Deinen Anwender*innen einen "Platz" geben für "hier was auch immer Ihr für rm benutzt". Die OO-Fuzzis nennen sowas "mixin". Man kann den Kopf so oder auch so drehen :-)
Zusatzfrage: Wenn ein Script wie meines gerade aus Funktionen besteht: Am Ende der Funktionsdefinitionen werden die aufgerufen. Kann man z.B. zum Testen, diese Funktionen (aus einer echten) Shell auch einzeln aufrufen?
How do the masters do it?
Einen netten Ansatz findest Du bei den alten sysvinit-Skripten. Die ersten zwei Zeilen (abgesehen von Kommentaren) in einem (Quizfrage: welches?) von meinen sehen so aus:
[ -r /usr/share/postgresql-common/init.d-functions ] || exit 0 . /usr/share/postgresql-common/init.d-functions
Es wird eine Datei "gesourct", in der irgendwelche nützliche Funktionen definiert werden. Das würde ich mal das "library"-Pattern nennen.
Konkret: Wenn value=10 vor dem Aufruf von init.d-functions steht, dann ist value dort bekannt. Aber was wenn ich in init.d-functions value2=20 setze. Kann ich die 20 in dem aufrufenden Vater-Script verwenden?
Nicht in einem "Unterskript". Aber in einer Funktion. Die Frage ist, ob Du das /willst/. Du siehst Deinem Hauptskript nicht an, ob eine Variable zwei Stockwerke tiefer verändert wird. Vielleicht passiert das nur aus Versehen, weil jemand "da unten" auch den Namen $BLUNTSCHLI für was ganz anderes verwendet wurde?
Entweder machst Du dazu also Gebrauch vom Library-Pattern (s.o.), oder Du "gibst ein Ergebnis zurück". Da strenggenommen Shell-Funktionen nur eine Art (Integer) "Fehlercode" zurückliefern, kannst Du mit stdout arbeiten:
secret-name () { echo "rumpelstilzchen" }
SECRET=$(secret-name)
... so etwas funktioniert. Auch noch krasser:
SECRET=$(secret-name | sed -e s/u/ü/g)
Das schöne an dem Stil ist, dass Du in Deinem Hauptprogramm /siehst/, dass der Wert der Variable SECRET verändert wird.
[...]
Nehmen wir an, ich habe ein Skript, nennen wir es "muuh":
#!/bin/bash echo "Guten Morgen"
say-hello () { echo hello }
say-good-bye () { echo good bye }
Und dann "source" ich das Ding in einem anderen:
... . muuh ...
Ok aber kann ich auch (Syntax frei erfunden) . muh::say-hello() machen und dann wird nur "hello" zurückgebeben. Das meine ich, wenn ich die Funktionen eines Scripts testen will.
Nö, sowas wie namespaces gibt es nicht.
Bei mir wäre gegenwärtig das Problem das das muh wohl so aussieht:
#/bin/sh funk1() { echo 1 } funk2() { echo 2 } funk3() { echo 3 } echo Test funk1 echo blabla funk3 funk2
Ich müsste zum Test die unteren 5 Zeilen komplett rausnehmen und source muh.sh funk2
machen um nur funk2 zu testen, richtig?
(Syntax-Anmerkung: nach "echo 1" usw muss wahrscheinlich ein ; sein)
Richtig. Der erste Stück geht in eine eigene Datei, my-functions, der zweite benutzt das. Das ist vermutlich die "lesbarste" Variante. Nicht die einzige. Eine andere:
#!/bin/sh # datei: muh fun1 () { ... } ... if [ -n "$TESTING" ] ; then exit 0 ; fi
echo blabla
Also: wenn die Variable TESTING gesetzt ist, dann hüpfst Du raus, nachdem die Funktionen definiert wurden aber bevor der Schaden angerichtet ist. Mir gefällt die Variante nicht so sehr, aber sie soll ja Dir gefallen :-)
Was passiert ist, dass wenn die Ausführung in meinem Skript an diesen Punkt kommt, "Guten Morgen" ausgegeben wird (wohin immer gerade stdout zeigt) und die zwei Funktionen definiert werden, die ich dann im weiteren Verlauf verwenden kann.
Immerhin. Also sind die Funktionen auch nach Ausführung noch verfügbar.
Ja, im Skript immer.
Ein ganz gerader, naiver Interpreter: mach' dies, dann mach' das [...]
Also vielen Dank für die Mühe, dann werd ich mich mal ans refactoring machen und mit kleinen Demos beginnen.
Gerne :)
lg
Hallo Arno,
On 8/1/22 17:17, Arno wrote:
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. Da wird z.B. eine Textdatei aus dem System geparst und daraufhin bestimmte Variablen und auch Pfade gesetzt. Diese werden dann im weitere Verlauf genutzt und zu verschiedenen Aktivitäten führen. Soweit so normal.
..ooOO(Hmm, anno 2022 sind sh-Skripte in rc5.d/Sxx nicht mehr sooo normal, oder? :-)
Jetzt ist mein script schon etwas länglich geworden und es droht die Übersicht verloren zu gehen. Also hab ich es in Funktionen aufgeteilt. Damit wird das script aber nicht kürzer. Das ganze möchte ich etwas wartungsfreundlicher und lesbarer gestalten. Ideal wäre ein einem Startscript die Variablen/Pfade zu setzen und dann bestimmte Unterscripts zu starten. Was aber dabei ein Problem zu sein scheint: a) die Variablen vom Startscript übernehmen b) Variablen im Idealfall auch noch von Unterscript zu Unterscript weiterreichen
Hierzu wurde ja schon einiges beigetragen. Mein Reflex wäre ein Skript, das die beschriebene Komplexität erreicht hat, in was anderem als plain Shell zu schreiben. Ich würde vermutlich Python bevorzugen, aber je nach Gusto gibt es ja viele weitere Möglichkeiten (Perl, Bash, Node, rust, C, ...).
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus.
Was ist der relevante Unterschied zwischen einem Skript, das von init aufgerufen wird und einer "klassischen Shell"?
Liebe Grüße Uwe
On Tue, Aug 02, 2022 at 11:22:31PM +0200, Uwe Kleine-König wrote:
Hallo Arno,
On 8/1/22 17:17, Arno wrote:
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. Da wird z.B. eine Textdatei aus dem System geparst und daraufhin bestimmte Variablen und auch Pfade gesetzt. Diese werden dann im weitere Verlauf genutzt und zu verschiedenen Aktivitäten führen. Soweit so normal.
..ooOO(Hmm, anno 2022 sind sh-Skripte in rc5.d/Sxx nicht mehr sooo normal, oder? :-)
Also bei mir... sind 34 Stück davon. Debian Bullseye. Was auch immer "normal" ist ;-)
(Jaja, ich geb' ja zu, dass ich den Installer ein wenig gut zureden musste, aber nichts richtig schwieriges).
Hierzu wurde ja schon einiges beigetragen. Mein Reflex wäre ein Skript, das die beschriebene Komplexität erreicht hat, in was anderem als plain Shell zu schreiben. Ich würde vermutlich Python bevorzugen, aber je nach Gusto gibt es ja viele weitere Möglichkeiten (Perl, Bash, Node, rust, C, ...).
Ich habe dazu eine Schwelle, die bei ungefähr (sehr ungefähr) 200 Zeilen liegt. Wobei ich erst versuche, das Skript kleiner zu machen :)
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus.
Was ist der relevante Unterschied zwischen einem Skript, das von init aufgerufen wird und einer "klassischen Shell"?
Da hatten wir zwei Kandidaten: was anderes als die gewohnte Bash (mensch muss dann nach "bashisms" suchen) und eine andere Umgebung (environment variables). Zweiteres ist ganz lustig: debian-user sieht mindestens jeden Monat "warum funktioniert mein Cron-Job nicht?" einmal :)
lg
Hallo Arno,
im Prinzip wurde ja schon alles irgendwie gesagt. Aber ich möchte dir noch sagen wie ich so etwas immer mache.
Ich habe zb ein Datei mit den Variablen mein.env In mein.env steht zB value1=10 value2=20 ...
und ich habe eine Datei my_funcs.sh:
function hello { echo "Hello" } ...
und in meinem Haupt script sieht das dann so aus:
#!/bin/sh
. /path/to/mein.env . /path/to/my_funcs.sh
do something
Hier sind jetzt meine Variablen und auch meine Funktionen bekannt
ich hoffe das ist jetzt etwas klarer für dich.
Viele Grüße Toby
Am 01.08.22 um 17:17 schrieb Arno:
Beim booten läuft bei mir ein script. Gestartet aus einem rc5.d/Sxx. Da wird z.B. eine Textdatei aus dem System geparst und daraufhin bestimmte Variablen und auch Pfade gesetzt. Diese werden dann im weitere Verlauf genutzt und zu verschiedenen Aktivitäten führen. Soweit so normal.
Jetzt ist mein script schon etwas länglich geworden und es droht die Übersicht verloren zu gehen. Also hab ich es in Funktionen aufgeteilt. Damit wird das script aber nicht kürzer. Das ganze möchte ich etwas wartungsfreundlicher und lesbarer gestalten. Ideal wäre ein einem Startscript die Variablen/Pfade zu setzen und dann bestimmte Unterscripts zu starten. Was aber dabei ein Problem zu sein scheint: a) die Variablen vom Startscript übernehmen b) Variablen im Idealfall auch noch von Unterscript zu Unterscript weiterreichen
Erschwerend kommt hinzu, dass das ganze während des Bootens passiert, also nicht aus einer klassischen shell heraus. Ich meine, das nicht mal a) da so ohne weiteres geht. Oder gibt es da Tricks? Ich hab nicht so viel sinnvolles dazu gefunden oder ich hab nicht die richtigen keywords dazu.
Zusatzfrage: Wenn ein Script wie meines gerade aus Funktionen besteht: Am Ende der Funktionsdefinitionen werden die aufgerufen. Kann man z.B. zum Testen, diese Funktionen (aus einer echten) Shell auch einzeln aufrufen? Also nur einzelne Funktionen um das Step by Step zu testen. Wie gesagt, die Pfade/Variablen müssen gesetzt bleiben, sonst ist es sinnlos. Bei läuft dann immer nur das ganze Script... Wenn ich das richtig verstanden hab, kann man nur dann einzelne Funktionen eines scripts aufrufen, wenn es kein "main" gibt, also sozusagen nur Funktionen. Ist das wahr?
Schöne Woche, Arno