PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Shell Scripting - Verhalten von Funktionen verändern



-eraz-
17.06.10, 07:26
Hey,

ich hab da leider ein mittelschweres Problem in einem Bash Skript. Das Skript hat mehrere Funktionen und ich springe zwischen diesen hin und her. Die Art des Skripts macht es aber erforderlich, das ich zwischen den Funktionen hin- und herspringe und nicht gegenseitig aufrufe so wie es Defaultmäßig ist. Beispiel:

Es gibt eine Funktion funktion_eins und funktion_zwei. funktion_zwei wird von funktion_eins aufgerufen und wenn funktion_zwei beendet ist, macht funktion_eins seinen Rest fertig und genau das ist es was ich nicht will. Ich will, dass wenn funktion_eins funktion_zwei aufruft funktion_eins nix weiter mehr macht:


#!/bin/bash
funktion_zwei () {
echo "hallo ich bin nummer zwei"
}

funktion_eins () {
echo "Hallo ich bin die erste Funktion"
funktion_zwei
echo "funktion_zwei ist fertig und ich auch"
}

funktion_eins


Ich will also, dass funktion_eins nicht mehr sagt: "funktion_zwei ist fertig und ich auch" sondern das die zweite Funktion einfach aufgerufen wird und sich somit die erste beendet, auch wenn sie noch nicht fertig ist.

m.o.o.
17.06.10, 09:07
Hallo,

würde die Struktur des Shell-Skriptes anpassen, also mit if-Verzweigungen und Rückgabewerten der Funktionen arbeiten.

#!/bin/bash
funktion_zwei () {
echo "hallo ich bin nummer zwei"
return 0;
}

funktion_eins () {
echo "Hallo ich bin die erste Funktion"
funktion_zwei
if [ $? -eq 0 ]; then
return;
fi;
echo "funktion_zwei ist fertig und ich auch"
}

funktion_eins
Allerdings verstehe ich dein Problem auch nicht zu 100%...

Gruß, Florian

-eraz-
17.06.10, 09:23
Allerdings verstehe ich dein Problem auch nicht zu 100%...
Ja das ist klar, der Grund warum ich das brauche liegt einfach am Design des Skripts das ich gemacht habe. Dieses hat mittlerweile knappp 1000 Zeilen und ist halt schon recht komplex.

Warum und wieso ich das brauche könnte ich jetzt auch nicht erklären ohne einen riesen Roman zu schreiben, aber ich brauche es. Die Lösung mit den Returncodes ist für meinen Fall leider auch nicht Anwendbar. Das Skript hat halt ein paar kleinere Bugs, die ich nur mit der Antwort auf meine Frage lösen könnte.

m.o.o.
17.06.10, 09:37
Okay, eine Lösung, die mir noch einfällt, wäre die Funktionen in einzelne Shellskripte auszulagern und die Skripte mit exec /pfad/zum/skript.sh (anstatt dem Funktionsnamen) aufzurufen... aber die Variablenweitergabe/-"vererbung" ist dadurch recht kompliziert.

func1.sh:
#!/bin/bash

export test="bla"

echo "Hallo";

exec /pfad/zum/skript/func2.sh
#evtl. kann man PATH anpassen um die Pfadangabe zu vermeiden

echo "ooo";

func2.sh:
#!/bin/bash

echo "Funktion 2";
echo $test;

Ausgabe:
$ ./func1.sh
Hallo
Funktion 2
bla
$

-eraz-
17.06.10, 10:11
Das ginge theoretisch, aber wie du schon sagtest wirds mit den Variablen dann auch sehr umständlich zudem hätte ich so an die 20 Skripts, sehr unpraktikabel.

Blöde Sache irgendwie,... es wundert mich das die Frage im Netz nicht schon öfters gestellt wurde, zumindest kann ich nix finden... :-/

Roger Wilco
17.06.10, 10:15
#!/bin/bash

f2 () {
echo 'f2'
}

f1() {
f2 && return
echo 'f1'
}

f1

HBtux
17.06.10, 10:26
Es gibt eine Funktion funktion_eins und funktion_zwei. funktion_zwei wird von funktion_eins aufgerufen und wenn funktion_zwei beendet ist, macht funktion_eins seinen Rest fertig und genau das ist es was ich nicht will. Ich will, dass wenn funktion_eins funktion_zwei aufruft funktion_eins nix weiter mehr macht:

Mal ganz ehrlich. Ich verstehe auch nicht richtig was Du genau willst...

So wie ich verstanden habe, soll hinter dem Aufruf zur "funktion_zwei" innerhalb der "funktion_eins" nichts weiter ausgeführt werden.
Warum steht dann hinter dem Funktionsaufruf der Befehl echo "funktion_zwei ist fertig und ich auch"
Wenn Du diesen Befehl raus nimmst, dann wird ja auch nichts mehr ausgeführt....


Aktuell wird das Script gestartet.
Innerhalb des Script wird die funktion_eins gestartet.
Aus der funktion_eins wird funktion_zwei gestartet.
Wenn funktion_zwei fertig ist, wird funktion_eins weiter ausgeführt
Danach ist wird das Script beendet...

-eraz-
17.06.10, 10:51
@Roger Wilco
Das scheint es zu sein :) Könntest du mir erklären wie das funktioniert?

@HBTux
Weil in Funktion_zwei Aktionen stattfinden die über den weiteren Verlauf entscheiden. Entweder gehts weiter in Funktion_eins oder nicht.

Roger Wilco
17.06.10, 10:58
return verlässt schlicht und ergreifend den aktuellen Codezweig. Eine Ebene höher würde das Skript beendet. Im konkreten Fall beendet `f2 && return` die aktuelle Funktion (f1) sobald f2 erfolgreich (da wären wir wieder potentiell bei Return-Codes) beendet wurde.

Wenn f1 immer beendet werden soll, ersetzt du das && durch ein Semikolon.

m.o.o.
17.06.10, 11:11
Würde mal mal behaupten die Lösung von Roger Wilco ist syntaktischer Zucker für if-else-Verzweigungen. ;)

Roger Wilco
17.06.10, 11:17
Ich habe nie etwas anderes behauptet. ;)

-eraz-
17.06.10, 11:47
Ok, und gibts da auch eine Möglichkeit, wie ich je nach Rückgabewert von f2 entscheiden kann ob's bei f1 weiter geht oder nicht?

/edit
Wobei das dürfte ja dann einfach mit einem if else gehen, ich teste das mal schnell...
Das funktioniert,...


#!/bin/bash
f2 () {
echo 'f2'
if [ -e test ]; then
return 0
else
return 1
fi
}

f1() {
f2
if [ $? = 0 ]; then
echo 'f1'
else
return
fi
}

f1


Eigentlich eh ganz einfach ^^
Danke an Euch für die Hilfe!! :)

/edit2
Habs grad in mein Skript eingebaut und es macht nun genau das was ich will. Hach ich könnte Euch küssen :D
Vorallem die Information von Roger war in der Hinsicht Gold Wert:

return verlässt schlicht und ergreifend den aktuellen Codezweig. Eine Ebene höher würde das Skript beendet.