declare, export sind die gebräuchlichsten Befehle um Strings durchzureichen. Dies scheint aber nur in eine Richtung zu gehen und zwar vom Parent zum Child Prozeß, sprich vom Script in die Funktion. in die andere Richtung gestaltet sich das ganze recht eigensinnig. Entweder man führt die Funktion in einer Variable aus und hat so die Funktionsausgabe in der Variablen, oder die Ausgabe der Variable in der Funktion wird in eine Datei umgeleitet, die im Script dann wieder ausgelesen wird. Letzteres dauert aber länger und erfordert mehr Operationen ( Auslesen, auf SSD schrieben , einlesen , in variable schrieben ) In Schleifen mit einigen 10000 Zeilen summiert sich da jeder Sekundenbruchteil.
Konkret geht es um folgende Funktion :
Code: Alles auswählen
create_parsed_file () {
echo "1" > $PIDFile
SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for i in $(cat $GpxFile | grep -v time) ; do # processing all lines exerpt timestamp lines
if [[ -n $( grep ele <<< $i) ]] ; then
echo "$i" # print elevation lines
echo -en "\t<time>$(date +%FT%H:%M:%S.835Z -d @$Timestamp)</time>\n" # print timestamp line
Timestamp=$[$Timestamp + $Timestampinterval] # raise timestamp when adding timestamp line to file
else
echo "$i" # print all lines exerpt elevation
fi
# calculate progressbar values # TODO write counter to var instead of file
ProccessingLineCounter=$[$ProccessingLineCounter + 1] # proccessing line counter for progressbar calculation
sed 's/.*/'$ProccessingLineCounter'/' -i $PIDFile
# echo $ProccessingLineCounter > $PIDFile
# echo $ProccessingLineCounter >&2 export counter to parent script
done
IFS=$SAVEIFS
sleep 0.2
rm $PIDFile
}
Mit den beiden Werten sind prozentualer Fortschritt und Ladebalken recht einfach umzusetzen.
Der Knackpunkt ist allerdings das Schreiben des Schleifenzählers ( $ProccessingLineCounter ) aus der im Hintergrund laufenden Funktion ( & ) in eine Datei und das Auslesen der Datei im Script selbst um die Fortschrittsanzeige zu berechnen.
Code: Alles auswählen
sleep 0.2
GpxFileLineCount=$(cat "$GpxFile" | grep -cv time )
while [[ -f $PIDFile ]]; do
#PercentProcessing=$(cat $PIDFile)
#Percent100=$(cat $GpxFile | grep -v time)
#BarLength=20
progressbar $(cat $PIDFile) $GpxFileLineCount 20 && sleep 0.1
done
printf " ${CHECK_MARK}\n\n"
Ich hatte erst die Ausgabe der Funktion (create_parsed_file) direkt in ein Datei umgeleitet und die Funktion später einfach aufgerufen: create_parsed_file &
Code: Alles auswählen
funktion () {
echo foo
echo bar
} > result.file
Code: Alles auswählen
echo "$(create_parsed_file)" > "$GpxOutputFile" &
Problem dabei : Die Variable kann erst weiterverarbeitet werden wenn die Funktion/Schleife komplett durchlaufen ist. Für die Fortschrittsanzeige wird aber ein aktueller, auslesbarer Wert nach jedem Schleifendurchlauf benötigt.
Ein anderer Versuch war über zwei versch. Ausgaben ( stdout und stderr ) die Counterausgabe von der eigentlichen Ausgabe zu trennen. Das geht aber wieder nicht weil ich stderr entweder direkt im Terminal sehe oder stderr erst nach Schleifenende auslesbar ist. Gibt es eine Möglichkeit stderr direkt auszulesen WÄHREND die Funktion noch läuft ? Sowas in der Art :
Code: Alles auswählen
echo "$(create_parsed_file 2> $VARforWHILELOOP)" > "$GpxOutputFile" &