Hallo Jan, hallo Thomas, hallo Leute, Am Dienstag, 12. August 2003 01:09 schrieb Jan Trippler:
On Mon, 11 Aug 2003 at 22:20 (+0200), Thomas Moritz wrote:
Hallo zusammen, ich habe folgende Struktur am Laufen:
#!/bin/bash
zaehler=0
egrep -a -A1 ´(...egal...)´ "$myfile" | while read line do # [...] zaehler=`expr $zaehler + 1` # [...] done
exit
Solange ich $zaehler innerhalb der while-Schleife abfrage, bekomme ich die richtigen Werte. Frage ich $zaehler nach done ab, dann erhalte ich 0.
Das ist kein Fehler. Aus *man bash*, Abschnitt *Pipelines*: Each command in a pipeline is executed as a separate process (i.e., in a subshell). [...] Die while-Schleife läuft also in einer Subshell, und die dort verwendeten Variablen findest Du in der aufrufenden Shell (dem Script) nicht wieder.
ACK
Ich sehe 3 Varianten (alles ungetestet):
1. temp. Datei: [...] 2. Kommandosubstition: [...] 3. Unter Umständen kannst Du auf die Pipe verzichten: [...]
4. geschickte Ausweitung der Subshell ;-) Stark verkürztes Beispiel: #!/bin/bash zaehler=0 echo -e "a\nb\nc\nd" | { # ^----- hier startet die Subshell while read line do zaehler=`expr $zaehler + 1` done echo Anzahl: $zaehler exit } # erst hier endet die Subshell! Erklärung aus man bash: { list; } list is simply executed in the current shell envi- ronment. list must be terminated with a newline or semicolon. This is known as a group command. The return status is the exit status of list. Note that unlike the metacharacters ( and , { and } are reserved words and must occur where a reserved word is permitted to be recognized. Since they do not cause a word break, they must be separated from list by whitespace. BTW: Du verwendest Backticks, um die Variable "$zaehler"eins hochzuzählen: zaehler=`expr $zaehler + 1` Das startet ein externes Programm in einer Subshell - wenig performant ;-) Genausogut funktioniert die (vermutlich bash-spezifische) Variante zaehler=$(($zaehler+1)) - und das ohne Subshell ;-) Eine weitere Variante ohne Subshell wäre let zaehler=$zaehler+1 Und ich dachte schon, TMTOWTDI gilt nur für Perl ;-))) Gruß Christian Boltz -- Das Problem ist vermutlich auf schlechte Erdung zurueckzufuehren. Schlagt einfach zwei Stahlnaegel in die Turnschuhe eures MCSEs. So koennen die Ueberspannungen aus dem Kopf abfliessen, und Euer Mann achtet auch mehr auf seine Sicherheit in der Naehe von Computern. [M. Liss in dasr]