ubuntuusers.de

while-loop > $file. Teilausgabe > STDOUT

Status: Gelöst | Ubuntu-Version: Kein Ubuntu
Antworten |

mephisto

Avatar von mephisto

Anmeldungsdatum:
12. Januar 2010

Beiträge: 63

Wohnort: Schweiz

Hallo allerseits

Bräuchte mal wieder eure Hilfe:

Ich habe ein bash-script mit einem while-loop, der in ein File schreibt und genau eine Stunde dauert. Ich möchte (in diesem Loop) zusätzlich Ausgaben über den Fortschritt generieren, die in STDOUT landen sollten.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
count=0
while true; do
    # here do something that produces output to write to file
    sleep 1
    let count+=1
    if (( $count % 60 == 0 )); then
        echo -en "\e[0K\r$(($count/60)) minutes passed." # <-- !!! Das sollte im Terminal auftauchen !!!
    fi
    if [ $count -eq 3600 ]; then
        break
    fi
done > $file

Vielen Dank für eure Zeit!

mephisto

(Themenstarter)
Avatar von mephisto

Anmeldungsdatum:
12. Januar 2010

Beiträge: 63

Wohnort: Schweiz

Hab ich wohl mal wieder den Wald vor lauter Bäumen nicht gesehen...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
count=0
while true; do
    # here do something that produces output to write to file > $file  <-- Hier bereits umleiten und nicht den ganzen Loop
    sleep 1
    let count+=1
    if (( $count % 60 == 0 )); then
        echo -en "\e[0K\r$(($count/60)) minutes passed."
    fi
    if [ $count -eq 3600 ]; then
        break
    fi
done

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13213

mephisto schrieb:

Hab ich wohl mal wieder den Wald vor lauter Bäumen nicht gesehen...

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
count=0
while true; do
    # here do something that produces output to write to file > $file  <-- Hier bereits umleiten und nicht den ganzen Loop
    sleep 1
    let count+=1
    if (( $count % 60 == 0 )); then
        echo -en "\e[0K\r$(($count/60)) minutes passed."
    fi
    if [ $count -eq 3600 ]; then
        break
    fi
done

Es gibt noch eine andere Möglichkeit:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20

# open fd 6 to "$file"
exec 6>"$file"

count=0
while true; do
    # here do something that produces output to write to file > $file  <-- Hier bereits umleiten und nicht den ganzen Loop
    echo "a message for file" >&6
    sleep 1
    let count+=1
    if (( $count % 60 == 0 )); then
        echo -en "\e[0K\r$(($count/60)) minutes passed."
    fi
    if [ $count -eq 3600 ]; then
        break
    fi
done

# close fd 6
exec 6>&-

Dabei bleibt die Datei die ganze Zeit offen. Das macht einen Unterschied, falls die $file irgendwann einmal umbenannt wird. Außerdem ist es minimal effizienter. Das wird in Deinem Fall nicht auffallen, aber bei Skripten, die viele Ausgaben erzeugen, kann das wiederholte Öffnen und Schließen der Datei einen Unterschied machen.

Ich würde die Abbruchbedingung übrigens in die Schleife packen - das ist eleganter und lesbarer:

1
2
3
4
5
6
count=0

while [ $((count += 1)) -le 3600 ]; do
  sleep 1
  # ...
done

In der bash kannst Du auch eine for-Schleife nehmen

1
2
3
4
for (( c=1 ; c <= 3600 ; ++c )); do
  sleep 1
  # ...
done

Ciao

robert

D630

Avatar von D630

Anmeldungsdatum:
24. Juli 2013

Beiträge: 329

exec 6<> "$file" würde zwar zum Lesen und Schreiben öffnen; aber der kleine Vorteil dabei: Wenn die Datei nicht existiert, wird sie zuvor kreiert.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13213

D630 schrieb:

exec 6<> "$file" würde zwar zum Lesen und Schreiben öffnen; aber der kleine Vorteil dabei: Wenn die Datei nicht existiert, wird sie zuvor kreiert.

$ ls foobar
ls: cannot access foobar: No such file or directory
$ exec 6>foobar
$ exec 6>&-
$ ls foobar
foobar 

D630

Avatar von D630

Anmeldungsdatum:
24. Juli 2013

Beiträge: 329

rklm schrieb:

D630 schrieb:

exec 6<> "$file" würde zwar zum Lesen und Schreiben öffnen; aber der kleine Vorteil dabei: Wenn die Datei nicht existiert, wird sie zuvor kreiert.

$ ls foobar
ls: cannot access foobar: No such file or directory
$ exec 6>foobar
$ exec 6>&-
$ ls foobar
foobar 

Ah, jetzt weiß ich endlich, was ich immer verkehrt gemacht habe! Ich habe immer mit 'exec n>>word' geöffnet...

edit:

Nee, doch nicht. Da muss ich nochmals drüber nachdenken. Notiz fürs nächste Mal: Erst testen, dann posten.

rklm Team-Icon

Projektleitung

Anmeldungsdatum:
16. Oktober 2011

Beiträge: 13213

D630 schrieb:

Ich habe immer mit 'exec n>>word' geöffnet...

Das führt lediglich dazu, dass an die Datei angehängt wird, wenn sie schon da ist. Meine Variante bügelt die Datei (es sei denn, es ist die bash und Option set -C für "noclobber" ist gesetzt - dann braucht man exec 6>|"$file").

Nee, doch nicht. Da muss ich nochmals drüber nachdenken. Notiz fürs nächste Mal: Erst testen, dann posten.

😬

D630

Avatar von D630

Anmeldungsdatum:
24. Juli 2013

Beiträge: 329

Ja, aber irgendeinen Fehler habe ich immer damit assoziiert. Mal sehen

😉

Antworten |