Variablen in Shellscript

Hi…

Wie bekomme ich bei folgendem Script den Endwert von $PARTS aus der while-Schleife heraus?

start\_device()
{
 DEV="$1"
 PARTS=""
 read\_param $DEV device | while read REPLY;
 do
 set -- $PARTS
 PARTS="$PARTS $REPLY"
 echo "$PARTS";
 done;

 echo "--\> $PARTS";
}

Ich versuche gerade, das raidtools-Startscript auf meine Bedürfnisse umzustricken. Die Funktion „read_param $DEV device“ gibt alle Partitionen aus, die Teil des Arrays $DEV sind.
Die echos sind nur zur Fehlersuche. Momentan bekomme ich eine Ausgabe in der Art:

/dev/hde1
/dev/hde1 /dev/hdf1
/dev/hde1 /dev/hdf1 /dev/hdg1
/dev/hde1 /dev/hdf1 /dev/hdg1 /dev/hdh1
--\>

Die Devices werden also wunderschön der Reihe nach an $PARTS angehängt, aber nach dem done ist $PARTS wieder leer :frowning:

genumi

Hi,

Wie bekomme ich bei folgendem Script den Endwert von $PARTS
aus der while-Schleife heraus?

[…]

Die Devices werden also wunderschön der Reihe nach an $PARTS
angehängt, aber nach dem done ist $PARTS wieder leer :frowning:

Ich habe Dein Skript mal kopiert und der Einfachheit halber mal eine Textdatei als Input-Geber verwendet.

Deine Variante:

start\_device()
{
 DEV="$1"
 PARTS=""
 cat $DEV | while read REPLY;
 do
 set -- $PARTS
 PARTS="$PARTS $REPLY"
 echo "$PARTS";
 done

 echo "--\> $PARTS";
}

bringt:

 eins
 eins zwei
 eins zwei drei
 eins zwei drei vier
--\>

Dann habe ich eine kleine Änderung vorgenommen:

my\_start\_device()
{
 DEV="$1"
 PARTS=""
 while read REPLY;
 do
 set -- $PARTS
 PARTS="$PARTS $REPLY"
 echo "$PARTS";
 done $PARTS";
}

Die bringt:

 eins
 eins zwei
 eins zwei drei
 eins zwei drei vier
--\> eins zwei drei vier

Klar, Die Dateiverarbeitung in meinem Beispiel ist für Deine Funktions-Ausgabe nicht verwendbar, aber vielleicht trägt die Info ja zur Lösung bei. Könnte mir vorstellen, dass das „Pipen“ hier das Problem ist.

Gruß,
Thomas

Nachtrag:

Es kommt noch besser, wenn man PARTS einen Startwert gibt:

start\_device()
{
 DEV="$1"
 PARTS="hallo"
 cat $DEV | while read REPLY;
 do
 set -- $PARTS
 PARTS="$PARTS $REPLY"
 echo "$PARTS";
 done

 echo "--\> $PARTS";
}






hallo eins
hallo eins zwei
hallo eins zwei drei
hallo eins zwei drei vier
--\> hallo

Gruß,
Thomas

O.K., ein Hinweis noch, dann lass ich die Experten zum Zug kommen! :smile:

http://lists.suse.com/archive/suse-linux/2000-Oct/01…

Hier hat jemand das gleiche Problem wie Du!

Gruß,
Thomas

Hi…

Hallo,

Wie bekomme ich bei folgendem Script den Endwert von $PARTS
aus der while-Schleife heraus?

Das Problem ist nicht das while, sondern die subshell, in der Du es ausfuehrst. Subshells koennen die Umgebung der darueber befindlichen Shell nicht veraendern.

> start\_device()  
> {  
> DEV="$1"  
> PARTS=""  
> read\_param $DEV device | while read REPLY;  
> do  
> set -- $PARTS

Warum setzt Du hier die positional parameters neu?

> PARTS="$PARTS $REPLY"  
> echo "$PARTS";  
> done;  
>   
> echo "--\> $PARTS";  
> }

Ich weiss ja nicht, aber warum nicht einfach:

PARTS=`read_param $DEV device`

Haengt natuerlich davon ab, wie das konkret aussieht, aber hier laeuft das auf das gleiche hinaus.

Und wenn’s halt unbedingt mit subshell sein soll:

parts=`cat /dev/magic/parts |while read line; do parts="$parts $line"; echo "Debug: $parts" \>&2; done; echo "$parts"`

(Untested.)

Die Devices werden also wunderschön der Reihe nach an $PARTS
angehängt, aber nach dem done ist $PARTS wieder leer :frowning:

Weil die subshell und die darin enthaltene Umgebung weg ist.

HTH,
Gruss vom Frank.

Hi…

Wie bekomme ich bei folgendem Script den Endwert von $PARTS
aus der while-Schleife heraus?

Das Problem ist nicht das while, sondern die subshell, in der
Du es ausfuehrst.

Ja, das hat CupRacer auch schon festgestellt.

Ich weiss ja nicht, aber warum nicht einfach:

PARTS=read_param $DEV device

Haengt natuerlich davon ab, wie das konkret aussieht, aber
hier laeuft das auf das gleiche hinaus.

Geht so leider nicht, weil read_param eine Funktion und kein Befehl ist - oder stelle ich mich jetzt wirklich blöde an? Einfache Shellscripts hab ich halbwegs im Griff, aber wie Funktionen funktionieren verstehe ich nur in „richtigen“ Programmiersprachen.

genumi

PARTS=read_param $DEV device

Geht so leider nicht, weil read_param eine Funktion und kein
Befehl ist - oder stelle ich mich jetzt wirklich blöde an?

Ich weiss nicht:

frank@bane [~] $ cat foo.sh
#!/bin/sh

func()
{
 echo "Ausgabe aus func(): $1"
}

func rabarber

foo=`func laber`

echo "Das kam aus func() zurueck: $foo"
frank@bane [~] $ ./foo.sh
Ausgabe aus func(): rabarber
Das kam aus func() zurueck: Ausgabe aus func(): laber
frank@bane [~] $

Einfache Shellscripts hab ich halbwegs im Griff, aber wie
Funktionen funktionieren verstehe ich nur in
„richtigen“ Programmiersprachen.

Ist hier nicht viel anders.

HTH,
Gruss vom Frank.

Hi…

PARTS=read_param $DEV device

Geht so leider nicht, weil read_param eine Funktion und kein
Befehl ist - oder stelle ich mich jetzt wirklich blöde an?

Ich weiss nicht:

Aha. Daraus schliesse ich, daß ich nicht wirklich verstanden habe, was read_param tut. Ich kopier sie mal hier rein, zusammen mit einem Minimalscript zum ausprobieren. Danke schonmal für Deine bisherigen Hinweise, auch wenn sie mich nicht weitergebracht haben - zumindest lern ich nebenbei interessante Kleinigkeiten.

#!/bin/sh
CONFIG=./raidtab


read\_param() # $1: raiddev $2: param-name
{
 DEV="$1"
 PARAM="$2"

 sed 's/#.\*$//' $CONFIG | while read REPLY;
 do
 set -- $REPLY

 if ["$1" = raiddev] && ["$2" = $DEV]; then
 while read REPLY;
 do
 set -- $REPLY

 if ["$1" = raiddev];
 then
 break
 fi

 if ["$1" = $PARAM];
 then
 echo $2
 fi
 done
 return
 fi
 done
}

start\_device()
{
 DEV="$1"
 PARTS=""
 read\_param $DEV device | while read REPLY;
 do
 PARTS="$PARTS $REPLY"
 echo "$PARTS";
 done;

 echo "$MDADM -A $DEV --\>$PARTS";# && echo -n "$DEV "
}


start\_device /dev/md4

Dazu brauchts dann noch eine ./raidtab, die so in der Art aussieht:

raiddev /dev/md4
 device /dev/hde1
 device /dev/hdf1
 device /dev/hdg1
 device /dev/hdh1

Gibt es vielleicht eine bessere Methode, so eine Konfigurationsdatei einzulesen? Ich möchte halt nicht die Devicenamen im Script haben, denn das wäre weder elegant noch flexibel…

genumi