PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Variable aus while-Schleife



09-02-2001, 16:35
Hallo,

ich habe mit der folgenden Konstruktion ein Problem:

RET=1
cat /etc/passwd | while read LINE
do
BENU=`echo ${LINE} | awk -F: ' { print $1 } '`
if [ ${BENU} = "root" ]
then
RET=0
break
fi
done

exit ${RET}

Unter HP-UX wird RET korrekt gesetzt, unter Linux (bash, ksh) ist der exit-Status immer 1, es sieht so aus, als ob innerhalb der while-Schleife eine eigene Shell aufgemacht wird, was übrigens auch erklären würde, daß ein exit denselben Effekt erbringt wie ein break.

11-02-2001, 22:14
Hallo Kay,

wenn du sowieso schon mit dem awk arbeitest, warum liest du die Datei nicht gleich zeilenweise mit diesem Tool ein (getline()).

Im übrigen lässt sich nachstehendes Script wesentlih leichter Lesen (und kontrollieren).


RET=1
cat /etc/passwd | while read LINE; do
BENU=`echo ${LINE} | awk -F: ' { print $1 } '`
if [ ${BENU} = "root" ]; then
RET=0
break
fi
done
exit ${RET}

http://www.linuxforen.de/ubb/confused.gif muss das wirklich exit ${RET} heißen? http://www.linuxforen.de/ubb/confused.gif
vielleicht weiß jemand einen Rat.

Hans

11-02-2001, 22:17
Da gebe ich mir soviel mühe Struktur in das Programm zu bekommen, und dann klaut einem da einer die führenden Leerzeichen! Sorry http://www.linuxforen.de/ubb/frown.gif

Hans

thommy
12-02-2001, 09:07
In älteren Bashversionen (irgendwann vor 2.0) wurde für while tatsächlich eine eigene Shell eröffnet. Es besteht jedoch die Möglichkeit, über Filedeskriptoren das Problem zu umgehen:

<pre>
RET=1

exec 4&lt;&0 &lt; /etc/passwd

while read LINE
do
BENU=`echo ${LINE} | awk -F: ' { print $1 } '`
if [ ${BENU} = "root" ]
then
RET=0
break
fi
done

exec 0&lt;&4
exec 4&lt;&-

exit ${RET}
</pre>

Thomas

13-02-2001, 07:48
Hallo allerseits,

erst einmal vielen Dank für die Antworten. Das grundsätzliche Problem war nicht so sehr das Auslesen der /etc/passwd. Vielmehr geht es darum, Daten, die man innerhalb der Schleife gewonnen hat, auch außerhalb zu nutzen.
Bsp:
RET=1
AA=0
while :
do
AA=`expr $AA + 1`
echo $AA
if [ $AA -gt 5 ]
then
RET=0
exit 7
fi
done
echo "nach Schleife: AA=$AA RET=$RET"
exit 0

Die Variablen, die innerhalb der Schleife gesetzt wurden, behalten Ihre Werte auch nach verlassen der Schleife.


Wenn man jetzt "while :" mit
"cat /etc/passwd | while read LINE"
ersetzt, sind die Werte, die innerhalb der Schleife gesetzt werden, nach der Schleife nicht mehr sichtbar. Außerdem springt der "exit 7" lediglich aus der Schleife heraus, nicht aber aus dem Script.
Kennt sich jemand so gut mit den Interna der Shell aus, daß er mir den Grund nennen kann?

P.S. Inzwischen wissen wir, daß sich Solaris wie Linux verhält, vielleicht ist HP-UX ja die Ausnahme?

13-02-2001, 16:08
Hi,
das ist wirklich ein seltsames Verhalten der bash.

Viellecht ist ja

found=x`cat /etc/passwd | cut -d: -f1| grep root`
if [ $found = "xroot" ];
then
exit 0
else
exit 1
fi

portabler

14-02-2001, 13:02
Das ist aber eine ausgesprochen huebsche und elegenate Loesung ;-)

Manchmal sieht man eben den Wald vor lauter Baeumen nicht.

*mich-frag-wie-ich-nicht-daran-denken-konnte-naja-vieleicht-ich-einfach-alt-werde-oder-liegts-am-alkohol-oder-am-fachidiotismus-oder-bin-ich-einfach-zu-bloed-hilfe-ich-verbringe-vi el-zu-viel-zeit-an-dieser-bloeden-kiste-jetzt-mach-ich-erst-mal-ne-pause-tschuess*

14-02-2001, 14:36
Noch einmal vielen Dank, statt | werde ich in Zukunft versuchen die andere Lösung zu nutzen.

15-02-2001, 00:17
Aha,

info bash ->
...
Each command in a pipeline is executed in its own subshell (*note
Command Execution Environment::.). The exit status of a pipeline is
the exit status of the last command in the pipeline. If the reserved
word `!' precedes the pipeline, the exit status is the logical negation
of the exit status of the last command.
...

So funktionierts:

cat /etc/passwd | {
RET=1
while read LINE
do
BENU=`echo ${LINE} | awk -F: ' { print $1 } '`
if [ ${BENU} = "root" ]
then
RET=0
break
fi
done
exit ${RET}; }
!Wichtig: der Semikolon vor der letzten Klammer!

bye

thommy
15-02-2001, 00:31
Das Bearbeiten einer Datei in einer while-Schleife lässt sich eleganter lösen:

<pre>
while read line; do
# tue etwas
done &lt; /etc/passwd
</pre>


Thomas