while, klammerausdruck wird nur einmal ausgewertet

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
Benutzeravatar
LenaLuna
Beiträge: 43
Registriert: 16.04.2006 11:29:23
Wohnort: Zürich / Schweiz
Kontaktdaten:

while, klammerausdruck wird nur einmal ausgewertet

Beitrag von LenaLuna » 13.03.2007 09:02:09

hallo zusammen,

haben folgendes problem:

Code: Alles auswählen

#!/bin/sh

var=0

fu()
{
	var=$[++var]

	if [ "$var" -gt 10 ]
	then
		return 1
	fi

	echo $var

	return 0
}

while zahl=$(fu)
do
	echo $zahl
done
die funktion fu im obigen code macht nichts anderes als $var um 1 erhöhen und über echo ausgeben.
sobald der wert 10 erreicht ist, wird fu anstatt mit return 0, mit return 1 beendet. das funktioniert soweit auch korrekt.

in der whileschleife wird die echo ausgabe der funktion der variablen $zahl zugewiesen.
in der schleife selbst wird diese variable mit echo wieder ausgegeben.

sobald der return-wert von fu 1 wird, sollte die schleife verlassen werden.
leider wird immer nur die erste erhöhung von $var, also 1, ausgegeben und die schleife läuft endlos.
es scheint so, als ob ein klammerausdruck nur einmal ausgewertet wird.

wenn ich die while-schleife wie nachfolgend aufbaue funktioniert das ganze:

Code: Alles auswählen

while fu
do
	:
done
nur ist das leider nicht genau das was ich will.
ich möchte die ausgabe von fu einer variablen zuweisen können.

hat jemand eine idee?

bitte fragt nicht nach dem sinn des skriptes.
ich habe es auf das grundproblem abgespeckt.

gruss lenaluna

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 13.03.2007 09:27:22

hier bleibt die globale Variable $var immer auf 0 und zahl wird daher immer auf 1 gesetzt:

Code: Alles auswählen

while zahl=$(fu)

Code: Alles auswählen

root@gms4:~# cat x.sh
#!/bin/sh

fu()
{
        local var=$1
        var=$[++var]

        if [ "$var" -gt 10 ]
        then
                return 1
        fi

        echo $var

        return 0
}

while zahl=$(fu $zahl)
do
        echo $zahl
done
root@gms4:~# ./x.sh
1
2
3
4
5
6
7
8
9
10
root@gms4:~#
Gruß
gms

Benutzeravatar
LenaLuna
Beiträge: 43
Registriert: 16.04.2006 11:29:23
Wohnort: Zürich / Schweiz
Kontaktdaten:

Beitrag von LenaLuna » 13.03.2007 09:55:05

danke gms für die schnelle antwort,

du sagst, dass $var immer auf 0 gesetzt wird.
warum funktioniert denn nachfolgendes skript?:

Code: Alles auswählen

#!/bin/sh

var=0

fu()
{
	var=$[++var]

	if [ "$var" -gt 10 ]
	then
		return 1
	fi

	echo $var

	return 0
}

fu
fu
fu
fu
fu
fu
fu
fu
fu
fu
lenaluna

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 13.03.2007 10:17:22

bei diesem Script bleibt "fu" in der gleichen Shell, daher verändert sich auch die globale Variable "var". Bei deinem ersten Script wird jedoch "fu" in einer Subshell aufgerufen und dort die globale Variable verändert, die globale Variable der Hauptshell bleibt davon unberührt.

Gruß
gms

Benutzeravatar
LenaLuna
Beiträge: 43
Registriert: 16.04.2006 11:29:23
Wohnort: Zürich / Schweiz
Kontaktdaten:

Beitrag von LenaLuna » 13.03.2007 10:25:09

wieder vielen dank gms,

das hatte ich auch vermutet.
darum habe ich jetzt $var exportiert.
dann sollte sie doch auch in den subshells zu verfügung stehen.
geht aber immer noch nicht :oops: .

Code: Alles auswählen

#!/bin/sh

export var=0

fu()
{
	export var=$[++var]

	if [ "$var" -gt 10 ]
	then
		return 1
	fi

	echo $var

	return 0
}

while zahl=$(fu)
do
	echo $zahl
done
gruss lenaluna

Benutzeravatar
Silke
Beiträge: 559
Registriert: 17.05.2005 15:58:20
Wohnort: Hannover
Kontaktdaten:

Beitrag von Silke » 13.03.2007 10:25:41

Moin,
LenaLuna hat geschrieben:danke gms für die schnelle antwort,

du sagst, dass $var immer auf 0 gesetzt wird.
warum funktioniert denn nachfolgendes skript?:
also da die Variablendeklaration außerhalb der Funktion steht, wird $var nur ein einziges Mal auf 0 gesetzt (ganz am Anfang) und dann nie wieder. Aber mir fällt etwas anderes auf:

Code: Alles auswählen

[..]
	if [ "$var" -gt 10 ]
	then
		return 1
	fi
[..]
Die Funktion gibt 1 zurück, wenn $var größer 10 ist, ansonsten 0 - also auch gleich beim ersten Schleifendurchlauf, weil $var da erst 1 ist, sodass der Ausdruck zahl=$(fu) unwahr wird und die Schleife nicht wieder durchlaufen wird. Probier mal mit -lt statt -gt.

Falls ich jetzt völligen Quatsch geschrieben haben sollte, liegt das daran, dass ich noch keinen Kaffee hatte :-)
Gruß,

- Silke -
Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann. Das Gegenteil ist schon schwieriger.
- Kurt Tucholsky -

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 13.03.2007 10:45:38

Silke hat geschrieben: Die Funktion gibt 1 zurück, wenn $var größer 10 ist, ansonsten 0 - also auch gleich beim ersten Schleifendurchlauf, weil $var da erst 1 ist
richtig
Silke hat geschrieben:sodass der Ausdruck zahl=$(fu) unwahr wird und die Schleife nicht wieder durchlaufen wird. Probier mal mit -lt statt -gt.
Der Variable "zahl" wird die Ausgabe der Funktion "fu" zugewiesen ( siehe "echo $var" ), von der while-Bedingung wird jedoch der Rückgabewert ausgewertet. Dieser ist/sollte bei den ersten 10 Duchläufen gleich 0 sein. Ein Kommando liefert im Fehlerfall einen Wert != 0, daher ist die while-Bedingung "true"

Code: Alles auswählen

root@gms4:~# false; echo $?
1
root@gms4:~# true; echo $?
0
Silke hat geschrieben: Falls ich jetzt völligen Quatsch geschrieben haben sollte, liegt das daran, dass ich noch keinen Kaffee hatte :-)
Quatsch war es auch keiner, hat auf alle Fälle logisch geklungen, aber Kaffe ist trotzdem angesagt :)

Gruß
gms

Benutzeravatar
LenaLuna
Beiträge: 43
Registriert: 16.04.2006 11:29:23
Wohnort: Zürich / Schweiz
Kontaktdaten:

Beitrag von LenaLuna » 13.03.2007 10:48:39

hallo silke,

beim shell-skripten und auch bei unix-kommandos ist der rückgabewert 0 wahr und alles andere unwahr.

daher wir die if-sektion betreten wenn das kommando einen rückgabewert von 0 hat.

Code: Alles auswählen

if kommando
then
    ...
fi
gruss lenaluna

Benutzeravatar
LenaLuna
Beiträge: 43
Registriert: 16.04.2006 11:29:23
Wohnort: Zürich / Schweiz
Kontaktdaten:

Beitrag von LenaLuna » 13.03.2007 10:50:26

doppelt gemoppelt hält besser....

Benutzeravatar
Silke
Beiträge: 559
Registriert: 17.05.2005 15:58:20
Wohnort: Hannover
Kontaktdaten:

Beitrag von Silke » 13.03.2007 12:09:10

Wusst ich doch, dass ich erst den Kaffee hätte abwarten sollen ... klar, 0 ist true. Damit komme ich regelmäßig durcheinander, zumal ich meistens in Sprachen programmiere, die 1 für wahr halten *g*

- Silke -
Der Vorteil der Klugheit liegt darin, dass man sich dumm stellen kann. Das Gegenteil ist schon schwieriger.
- Kurt Tucholsky -

Antworten