Shellscript-Problem: /bin/sh Funktion while return
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hallo Liste, ich zweifle an mir selbst. Ich habe schon hunderte von Scripten geschrieben, meistens unter Red Hat, aber auch unter Suse. Folgendes Script sollte eigentlich 0 oder eins zurückgeben, es gibt aber immer 0 zurück, da das return in der while-Schleife nicht zum Beenden der Funktion führt ... Bin ich jetzt total verblödet ? Linux: Suse 9.1 newserver:~ # /bin/sh -version GNU bash, version 2.05b.0(1)-release (i586-suse-linux) Copyright (C) 2002 Free Software Foundation, Inc. - ---schnipp--- #!/bin/sh testservice() { WHAT=$1 PPORT=$2 cat /etc/services|sed 's/ */ /' |\ while read NAME PORT REST do if [ "a$NAME" = "a$WHAT" -a "a$PORT" = "a$PPORT" ] then return 1 fi done return 0 } testservice PARAM1 PARAM2 RES=$? if [ $RES -eq 1 ] then irgendwas else sonstwas fi - ---schnipp--- Ich bin gespannt, was ihr dazu sagt ... Grüße Harry -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (MingW32) iD8DBQFEhBeO7ttRafA1ej8RAhWUAJ9SKDLBEm1gPUd5h10H38PAmrhevwCfStdK eGYZlQoV1dxN512PyXWyiQA= =5NiS -----END PGP SIGNATURE----- -- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-linux-unsubscribe@suse.com Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-linux-help@suse.com
Hallo Harry, hallo Liste, 2006-06-05 13:37 +0200, Harry Rüter:
Hallo Liste,
ich zweifle an mir selbst. Ich habe schon hunderte von Scripten geschrieben, meistens unter Red Hat, aber auch unter Suse.
Folgendes Script sollte eigentlich 0 oder eins zurückgeben, es gibt aber immer 0 zurück, da das return in der while-Schleife nicht zum Beenden der Funktion führt ...
Bin ich jetzt total verblödet ? - ---schnipp--- #!/bin/sh
testservice() { WHAT=$1 PPORT=$2
cat /etc/services|sed 's/ */ /' |\ while read NAME PORT REST do if [ "a$NAME" = "a$WHAT" -a "a$PORT" = "a$PPORT" ] then return 1 fi done
Hier statt return 0 folgendes: RET_VAL=$? return $RET_VAL So sollte es funktionieren.
}
testservice PARAM1 PARAM2 RES=$?
if [ $RES -eq 1 ] then irgendwas else sonstwas fi
- ---schnipp---
Ich bin gespannt, was ihr dazu sagt ...
Ich vermute, das ganze hängt damit zusammen, dass der erste 'return 1' nur die while-Schleife beendet, so dass 1 das return-Wert der Schleife ist. Danach wird aber nochmals 'return 0' ausgeführt. Wird aber die While-Schleife erfolglos durchgeführt, ist das return-Wert gleich 0. Meine Lösung speichert das return-Wert der While-Schleife und gibt dieses an den zweiten 'return' als Parameter weiter. Gruß Kimmo -- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-linux-unsubscribe@suse.com Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-linux-help@suse.com
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi Liste, hi Kimmo K. Elo schrieb:
Hallo Harry, hallo Liste,
cat /etc/services|sed 's/ */ /' |\ while read NAME PORT REST do if [ "a$NAME" = "a$WHAT" -a "a$PORT" = "a$PPORT" ] then return 1 fi done
Hier statt return 0 folgendes: RET_VAL=$? return $RET_VAL
So sollte es funktionieren.
Es funktioniert, aber irgendwie stelle ich mir die Frage warum es mit dem return direkt aus der while-Schleife heraus nicht klappt. Bisher war ich der Meinung, dass man mit return aus der Funktion rausspringt und mit break die Schleife beendet :o(
Ich vermute, das ganze hängt damit zusammen, dass der erste 'return 1' nur die while-Schleife beendet, so dass 1 das return-Wert der Schleife ist. Danach wird aber nochmals 'return 0' ausgeführt. Wird aber die While-Schleife erfolglos durchgeführt, ist das return-Wert gleich 0.
Meine Lösung speichert das return-Wert der While-Schleife und gibt dieses an den zweiten 'return' als Parameter weiter. Wie gesagt es funzt .... , danke für den Tipp
Gruß Kimmo Grüße Harry -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (MingW32)
iD8DBQFEhfHz7ttRafA1ej8RAqlbAKCNsyXvl92Ny4KiEsbeEmPjhYMy1QCfa0jC sG1JLOWwSZaMk47wkrwGgPk= =SmIx -----END PGP SIGNATURE----- -- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-linux-unsubscribe@suse.com Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-linux-help@suse.com
Hallo nochmals, 2006-06-06 23:21 +0200, Harry Rüter:
Es funktioniert, aber irgendwie stelle ich mir die Frage warum es mit dem return direkt aus der while-Schleife heraus nicht klappt.
Bisher war ich der Meinung, dass man mit return aus der Funktion rausspringt und mit break die Schleife beendet :o(
So sollte es auch sein (Auszug aus 'man return'): "return [n] Causes a function to exit with the return value specified by n. If n is omitted, the return status is that of the last command executed in the function body. If used outside a function, but during execution of a script by the . (source) command, it causes the shell to stop executing that script and return either n or the exit status of the last command executed within the script as the exit status of the script. If used outside a function and not during execution of a script by ., the return status is false." Ich habe dein Skript gedebuggt (gibt's so ein Wort?) und zwei 'echo'-Befehle eingefügt: --- cut here --- if [ "a$NAME" = "a$WHAT" -a "a$PORT" = "a$PPORT" ] then echo "Hier bin ich!" <--- HIER... return 1 fi done echo "Hier bin ich wieder!" <--- ... UND HIER return 0 --- cut here --- Ausgeführt so dass etwas gefunden wird:
sh harry.sh Hier bin ich! Hier bin ich wieder!
Also mit return wird nur die Schleife (while) beendet und man landet auf die Zeile nach 'done'. Die Erklärung dafür scheint zu sein, dass - AFAIK - pipes als "child processes" ausgeführt werden, so dass die while-Schleife als child-Prozess ausgeführt und entsprechend mit dem ersten 'return' beendet wird. Gruß Kimmo -- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-linux-unsubscribe@suse.com Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-linux-help@suse.com
Hallo nochmals, 2006-06-07 17:47 +0300, K. Elo:
Also mit return wird nur die Schleife (while) beendet und man landet auf die Zeile nach 'done'. Die Erklärung dafür scheint zu sein, dass - AFAIK - pipes als "child processes" ausgeführt werden, so dass die while-Schleife als child-Prozess ausgeführt und entsprechend mit dem ersten 'return' beendet wird.
Ich habe eine Expertin gefragt und sie bestätigte diese Annahme: die pipe führt dazu, dass die Schleife in einem Subshell ausgeführt wird, so dass mit 'return 1' nur aus dem Subshell rausgesprungen wird. Du merkst es auch so, wenn Du am Anfang der Funktion eine Integer-Variable deklariest (z.B. RET_VAL=0) und diese Variable vor 'return 1' auf 1 setzt. Wenn Du jetzt 'echo "$RET_VAL"' zwischen 'done' und 'return 0' einfügst, kommt _immer_ 0 aus. Wie Du sicherlich weißt, können Subshells nur ihre eigenen Variablen ändern, nicht aber die des Shells, das das Subshell gestartet hat. Gruß Kimmo -- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-linux-unsubscribe@suse.com Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-linux-help@suse.com
Hallo nochmals, ti, 2006-06-06 kello 23:21 +0200, Harry Rüter kirjoitti:
Es funktioniert, aber irgendwie stelle ich mir die Frage warum es mit dem return direkt aus der while-Schleife heraus nicht klappt.
Bisher war ich der Meinung, dass man mit return aus der Funktion rausspringt und mit break die Schleife beendet :o(
Eine Ergänzung meiner früheren Email von heute: Wegen des "Pipings" wird die ganze while-Schleife in einem subshell ausgeführt. Daher, AFAIK, gilt der erste 'return'-Befehl nur für dieses subsehell. Hmm... Gruß Kimmo -- Um die Liste abzubestellen, schicken Sie eine Mail an: suse-linux-unsubscribe@suse.com Um eine Liste aller verfuegbaren Kommandos zu bekommen, schicken Sie eine Mail an: suse-linux-help@suse.com
participants (2)
-
Harry Rüter
-
K. Elo