bash - Gültigkeitsbereich unklar

lordg2009

Lt. Commander
Registriert
Apr. 2009
Beiträge
1.503
Hi, habe ein Script mit folgendem Code

Code:
MYGLOBALVAR=""
ls | while read line
do
 if [[ ${#MYGLOBALVAR} -eq 0 ]]
 then
  MYGLOBALVAR="$line"
 fi
done
echo $MYGLOBALVAR

Am Ende ist die Variable leer, wie vor der Schleife definiert. Eigentlich müsste sie doch aber als Global definiert worden sein und sich in der Schleife ändern lassen, oder?
 
Hier das zutreffende Zitat aus der bash-Manpage (Section "SHELL GRAMMAR", "Pipelines"):
Each command in a pipeline is executed as a separate process (i.e., in a subshell).
Heißt, deine Variable wird in einer anderen Shell geschrieben und nicht in der, die das echo ausführt.

Eine Möglichkeit wäre hier z.B. direkt eine for-Schleife zu nehmen:
Code:
for line in $(ls); ...
 
ls ist nur für Menschen gedacht.

In einem Script machst du das einfach mit *

Code:
for file in *
do
    break
done

echo Die erste Datei ist "$file"...

Schwieriger wirds nur wenn du das irgendwie besonders sortiert haben willst...
 
Vielen Dank, klappt wunderbar. Mein Code war um einiges komplizierter, das 'ls' war nur zum darstellen des Problems.

Ich werde mit der bash wohl nie so richtig warm. Ständig irgendwelche Fehler die man macht. Da kommt man selbst mit C besser klar.
 
Naja, C muss man auch erst mal lernen.
Das wird schon mit Bash.
 
lordg2009 schrieb:
Ich werde mit der bash wohl nie so richtig warm. Ständig irgendwelche Fehler die man macht.
Was die Shell tut, empfindet man als weit weniger überraschend, sobald man mal versucht nachzuvollziehen, wie so eine Shell intern funktioniert, also wie sie das Skript zerlegt und ausführt. Dann ist die Lebensdauer deiner im Subprozess gesetzten Variable plötzlich vollkommen einleuchtend.

Shellskripte sind anders als übliche Programmiersprachen. Da hat sich niemand eine "schöne, konsistente, abgeschlossene Sprache" überlegt, die dem Programmierer das Leben leicht macht, sondern nur ein "Ding" erfunden, was vorhandene Fähigkeiten eines ganz bestimmten Betriebssystems irgendwie nutzbar macht. Die spezifischen Eigenschaften des Betriebssystems fliegen dir in Shellskripten ständig um die Ohren, während bei Programmiersprachen ala C viel mehr in der Sprachbeschreibung verlässlich definiert ist.

Eine kleine Shell (die Kommandos starten, Pipes und E/A-Umlenkung kann) ist "rein zufällig" nach helloworld.c oft eins der ersten Programme, an denen man sich versucht, um Unixe bischen kennenzulernen.

Vielleicht schaust du dir mal die bash-FAQ an. E4 behandelt deinen Fall.
 
Zuletzt bearbeitet:
Debugmeldungen einschalten hilft ungemein (#!/bin/bash -x oder als Befehl set -x).

Dann sieht man schon mal was da eigentlich ausgeführt wird nachdem das ganze Zeug erweitert worden ist.

Der Rest ist halt Erfahrung, wann eine Subshell aufgemacht wird muss man einfach wissen. Aber das passiert auch "alten Hasen" von Zeit zu Zeit daß man da nicht dran denkt und sich dann wundert warum die Variablen nicht stimmen. Den Fehler machst du halt einmal und beim nächsten Mal weisst du, ah da ist vielleicht ne Subshell irgendwo versteckt.

Bis man bei C mit den Pointern jonglieren kann dauert auch eine ganze Weile, da muss es auch erstmal klick machen und auch bei C gibts großes Fehlerpotential.

Es hilft wenn man auch sonst viel mit dem Terminal macht. Aber macht halt nicht jeder. Ist ja auch ok. ;)
 
Zurück
Oben