Bash syntax

$SHELL sei /bin/bash

for i in 5 4 3 2 1; do sleep "$i"s; echo $i & done

die o.g. zeile funktioniert nicht, und haette gern gewusst, wie ich sie richtig notieren muss.
ergebnis haette sein sollen, dass die zahlen in aufsteigender reihenfolge ausgegeben werden. dazu soll sleep die ausgabe verzoegern.

das eigentliche ziel der uebung war n prozesse zu starten, die aber nicht auf die vorher gestarteten warten.

any hints?
danke, gruss joerg

Hallo,

for i in 5 4 3 2 1; do sleep "$i"s; echo $i & done

for i in 5 4 3 2 1; do sleep „$i“; echo $i; done

das s ist bei sleep nicht nötig, per default nimmt er Sekunden an. Und du solltest eine ; statt & nehmen.

die o.g. zeile funktioniert nicht, und haette gern gewusst,
wie ich sie richtig notieren muss.
ergebnis haette sein sollen, dass die zahlen in aufsteigender
reihenfolge ausgegeben werden. dazu soll sleep die ausgabe
verzoegern.

Wenn du sie in aufsteigender Reihenfolge haben willst, dann solltest du sie auch in aufsteigender Reihenfolge hinschreiben:
for i in 1 2 3 4 5…

das eigentliche ziel der uebung war n prozesse zu starten, die
aber nicht auf die vorher gestarteten warten.

Ist das denn Absicht, dass die sleeps unterschiedlich lange warten?

Oder sollen die sleeps im Hintergrund starten? dann ist

for i in 5 4 3 2 1; do sleep „$i“& echo $i; done

das Richtige. Oder willst du gar, dass die sleeps im Hintergrund gestartet werden, und wenn eines beendet ist es die entsprechende Zahl ausgibt? dann ist

for i in 5 4 3 2 1; do (sleep "$i"s; echo $i)& done

wohl das was du suchst. Die „Magie“ steckt hier darin, den Prozess und sein dazugehöriges „echo“ gemeinsam in einer Subshell im Hintergrund zu starten…

GrĂĽĂźe,
Moritz (der hofft, dass die richtige Alternative dabei war)

any hints?
danke, gruss joerg

$SHELL sei /bin/bash

for i in 5 4 3 2 1; do sleep "$i"s; echo $i & done

die o.g. zeile funktioniert nicht, und haette gern gewusst,
wie ich sie richtig notieren muss.
ergebnis haette sein sollen, dass die zahlen in aufsteigender
reihenfolge ausgegeben werden. dazu soll sleep die ausgabe
verzoegern.

Du musst das sleep und echo als eigenen Prozess ausführen, um beides in der Reihenfolge im Hintergrund laufen lassen zu können. Siehe dazu man bash, Abschnitt „Compound Commands“:

for i in 5 4 3 2 1; do ( sleep ${i}s; echo ${i} ) & done

funktioniert, dank.
wobei ich jetzt irritiert bin, was der unterschied zw. background, subshell und „eigener prozess“ ist.
man bash sagt:

If a command is terminated by the control operator &, the shell executes the command in the back­ground in a subshell.
…
(list) list is executed in a subshell.

warum ist ()& dann nicht doppelt?

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Oder willst du gar, dass die sleeps im
Hintergrund gestartet werden, und wenn eines beendet ist es
die entsprechende Zahl ausgibt? dann ist

for i in 5 4 3 2 1; do (sleep "$i"s; echo $i)& done

wohl das was du suchst. Die „Magie“ steckt hier darin, den
Prozess und sein dazugehöriges „echo“ gemeinsam in einer
Subshell im Hintergrund zu starten…

jupp, das war der gewuenschte effekt, damit ich leicht eindeutig sehen kann, wann was gestartet/beendet wurde.

man bash sagt:

If a command is terminated by the control operator &, the
shell executes the command in the back­ground in a
subshell.
…
(list) list is executed in a subshell.

warum ist ()& dann nicht doppelt?

Der wesentliche Teil ist „in the back­ground“. Die Klammerung sorgt nur dafür, dass die Kommandos in der Reihenfloge in einer Subshell abgearbeitet werden, auf die der aufrufende Prozess dann wartet. Diese Shell wird dann per & in den Hintergrund geschickt. Prinzipiell dient die Klammerung nur dazu, die Aufrufe von sleep und echo zu sequentialisieren, so dass das & die beiden als Einheit sieht.