[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bash Script Frage





Gerhard Meier wrote:
On Wed, Jul 13, 2005 at 06:44:24PM +0200, Mart Frauenlob wrote:

Das Script hab ich hier hochgeladen:
http://www.jeah.net/~x-link/ifarray

Kann es sein, daß ich Variablen innerhalb eines 'while' Loops nicht permanent bearbeiten kann?


Die Schleife faengt so an:


$IP addr show ${iface} | $GREP -w inet | while read data; do


Problem ist hier, dass eine Pipe eine Subshell oeffnet. Das
Problem hat jetzt nicht unbedingt was mit der while-Schleife zu
tun. Hier etwas anschaulicher:

	echo a | read a
	echo $a

Man wuerde "a" als Ausgabe erwarten. Stattdessen bekommt man nur
eine Leerzeile zu sehen. Die Variable "a" wird in einer Subshell
gesetzt. Wenn sich diese beendet (wenn die Pipe geschlossen
wird), ist auch die Variable weg. Da ich Bash nicht kann, sonder
nur sh, hier ein haesslicher Workaround (In Bash gehts bestimmt
schoener, und ohne named pipe):

Danke für die Erklärung.
Ich habe mir gestern noch einen Workaround gebastelt, welcher die Werte in Dateien schreibt und wieder ausliest (hässlich).
Die fifo Variante hat nicht funktioniert.
Auf jeden Fall hat mir ein Freund weitergeholfen und eine elegante funktionierende Lösung geboten.
Hier das Script in funktionierender Form:
http://www.jeah.net/~x-link/ifarray3

Nur zur Vollständigkeit hier seine Erläuterung:

$IP addr show ${iface} | $GREP -w inet | while read data; geht
deswegen nicht, weil die | einen neuen subprozess startet. Und dieser
hat keinen Zugriff auf die Variablen des Vaters. (Erzeugt sich also
ein eigenes INTERFACE_ARRAY, und das ist natürlich wieder weg, wenn er
wieder in den vaterprozess wechselt.
Sprich: Der Teil, der auf INTERFACE_ARRAY zugreifen will darf nicht
hinter einem | stehen.
Lösung: via Prozess-substitution, $IP addr show ${iface} | $GREP -w
inet wird in einem Unterprozess ausgeführt und die ausgabe an das
while (nun im Vaterprozess, da nicht gepiped) umgeleitet:

while read data; do done < <($IP addr show ${iface} | $GREP -w inet)
(kein leerzeichen zw. 2. < und Klammer)

MfG
Mart



Reply to: