Willkommen Gast. Bitte einloggen oder registrieren. Haben Sie Ihre Aktivierungs E-Mail übersehen?
24.07.2021, 22:38:00

.
Einloggen mit Benutzername, Passwort und Sitzungslänge

Mitglieder
  • Mitglieder insgesamt: 25776
  • Letzte: joba48
Statistiken
  • Beiträge insgesamt: 746689
  • Themen insgesamt: 60054
  • Heute online: 375
  • Am meisten online: 2287
  • (22.01.2020, 19:20:24)
Benutzer Online

Autor Thema:  Wie 2 Schleifen in einem bash Script gleichz. laufen lassen oder bessere Lösung  (Gelesen 685 mal)

0 Mitglieder und 1 Gast betrachten dieses Thema.

Der ursprüngliche Grund aus dem die hier von mir angebrachten Fragen entstanden sind, ist das ich folgendes mit einem Script machen möchte:

* eine Echoausgabe alle 1s
* die Echoausgabe im 1s Takt, soll in einem weiteren angebbaren Intervall von z.B. 10 Sekunden lang zugelassen und dann jeweils 20s nicht erfolgen

Mir nicht so recht klar wie man so etwas am besten macht. Mir scheint es zu gehen, wenn ich in einem Script eine Schleife mit einer anderen steuern könnte. Dazu könnte ich zwei Scheifen verwenden, die parallel und zeitgleich in dem Schript laufen, und wo das mit dem längeren Takt, die Schleife mit dem kürzeren Takt steuert.

Zwei Befehle könnte ich zeitgleich mit "&" starten, aber wie kann man zwei Scripte zeitgleich innerhalb einer .sh Datei starten ?

Oder gibt es einen ganz anderen und viel sinnvolleren Lösungsansatz in dem Fall ?

Im folgenden Fall, startet nur die Schleife 1, jedoch nie die Schleife 2:
#!/bin/bash
while true; do
    echo "Schleife 1 mit langem Takt, Ausgabe alle 10s,"
    echo
    sleep 10
done

while true; do
    echo "Schleife 2 mit kurzem Takt, Ausgabe alle 1s"
    echo
    sleep 1
done

Nachtrag:

Ich glaube das folgende wäre vlt. besser:
* Eine Schleife bauen, die abwechselnd 10 s lang ein "laufe" an das zweite Script übergibt und dann 20s lang ein "laufe nicht" an das zweite Script übergibt. Aber auch in dem Fall, ist mir nicht klar wie man so etwas praktisch macht.
« Letzte Änderung: 15.06.2021, 17:24:59 von John.Miller »

So laufen beide Schleifen gleichzeitig:
#!/bin/bash
while true; do
    echo "Schleife 1 mit langem Takt, Ausgabe alle 10s,"
    echo
    sleep 10
done &

while true; do
    echo "Schleife 2 mit kurzem Takt, Ausgabe alle 1s"
    echo
    sleep 1
done

So laufen beide Schleifen gleichzeitig:
Genial. Da bin ich echt nicht drauf gekommen. Danke.

Neben dem das das so machbar ist, finde ich es erstaunlich, das Beide Schleifen quasi zur selben Zeit starten und nicht etwa z.B. die zweite Schleife dazu startet, nachdem die erste ihre erste Runde durch ist.

Folgend noch eine Bonusfrage in die Runde:
* Bei folgendem Script ist es so, das wenn ich in der ersten Schleife die var a mit dem Wert 123 belege, kann ich diese wie erwartet per echo in der ersten Schleife aus geben.
* Den in der ersten Schleife definierten Wert kann ich jedoch nicht in der 2. Schleife per Echo aus geben.
* Wie kann man den Wert der Variable oder die Variable, von der ersten Schleife an die zweite übergeben ?

#!/bin/bash
while true; do
    echo "Schleife 1 mit langem Takt, Ausgabe alle 10s,"
    a=123
    echo $a # funktionierende Ausgabe
    echo
    sleep 10
done &

while true; do
    echo "Schleife 2 mit kurzem Takt, Ausgabe alle 1s"
    echo $a # nicht funktionierende Ausgabe
    echo
    sleep 1
done
« Letzte Änderung: 13.06.2021, 19:31:21 von John.Miller »

    * Wie kann man den Wert der Variable oder die Variable, von der ersten Schleife an die zweite übergeben ?

Indem du die Variable nicht in die Schleife legst sondern davor.
Bei dir ist das ja doch eher eine Konstante.
Andernfalls (wenn sich der Wert bspw. durch Berechnung ändert) müsstest du sie exportieren.
Wenn ich eine Variable vor einer Schleife definiere, wird sie auch in einer Schleife bekannt. Ok. Aber was ich möchte, ist eine Variable die in einer Schleife (im betrachteten Fall, in der Schleife 1) einen Wert zugewiesen bekommen hat, von der Schleife 1 aus, in der Schleife 2 bekannt machen. Gerne auch in dem man diese erst von der Schleife 1 aus außerhalb der Schleife bekannt macht und das sie von dort aus in der Schleife 2 bekannt wird.

Der ursprüngliche Grund aus dem die hier von mir angebrachten Fragen entstanden sind, ist das ich folgendes mit einem Script machen möchte:

* eine Echoausgabe alle 1s
* die Echoausgabe im 1s Takt, soll in einem weiteren angebbaren Intervall von z.B. 10 Sekunden lang zugelassen und dann jeweils 20s nicht erfolgen

#!/bin/bash

while true; do

    if (( ++i <= 10 )); then
        echo "Ausgabe alle 1s"
    fi

    if (( i >= 30 )); then
        i=0
    fi

    echo
    sleep 1

done
« Letzte Änderung: 14.06.2021, 04:03:59 von Nessie »

#!/bin/bash

while true; do

    if (( ++i <= 10 )); then
        echo "Ausgabe alle 1s"
    fi

    if (( i >= 30 )); then
        i=0
    fi

    echo
    sleep 1

done

Ohh. Danke.

Das habe ich jetzt so angepasst.

#!/bin/bash

laufdauer=10
pausendauer=20
variable=$(($laufdauer+$pausendauer))
echo $variable

while true; do
    if (( ++i <= $laufdauer )); then
        echo "Ausgabe alle 1s"
    fi
    if (( i >= $variable )); then
        i=0
    fi
    echo
    sleep 1
done

« Letzte Änderung: 16.06.2021, 20:38:33 von John.Miller »

Hat jemand eine Idee wie ich in dem folgenden Beispiel, den Wert der in der ersten Schleife definierten Variable "$a" in der zweiten Schleife zugänglich machen kann, um ihn dort per "echo $a" ausgeben zu können ?

#!/bin/bash
while true; do
    echo "Schleife 1 mit langem Takt, Ausgabe alle 10s,"
    a=123
    echo $a # funktionierende Ausgabe
    echo
    sleep 10
done &

while true; do
    echo "Schleife 2 mit kurzem Takt, Ausgabe alle 1s"
    echo $a # nicht funktionierende Ausgabe
    echo
    sleep 1
done
« Letzte Änderung: 14.06.2021, 17:13:27 von John.Miller »

* eine Echoausgabe alle 1s
* die Echoausgabe im 1s Takt, soll in einem weiteren angebbaren Intervall von z.B. 10 Sekunden lang zugelassen und dann jeweils 20s nicht erfolgen
Mir ist nicht klar, warum es zwei Schleifen braucht? Hier mal zwei Beispiele mit einer Schleife - letzteres macht ungefähr, was du beschreibst:
#!/usr/bin/bash
i=0
while true; do
    sleep 1
    ((i++))
    echo "$i, Schleife 2 mit kurzem Takt, Ausgabe alle 1s"
    if [ $((i % 10)) -eq 0 ]; then
        echo "$i, Schleife 1 mit langem Takt, Ausgabe alle 10s"
        i=0
    fi
done
#!/bin/bash
i=0
while true; do
    sleep 1
    (( i++ ))
    if (( i <= 10 )); then
        echo "$i, Schleife 2 mit kurzem Takt, Ausgabe alle 1s"
    else
        echo "$i"
    fi
    if (( i == 30 )); then
        i=0
    fi
done

Edit:
Sehe gerade: Das hat @Nessie auch bereits in #4 vorgeschlagen. Und mein Code hat Verbesserungspotential.
Edit:
Mit Blick auf Antwort #4 habe ich meinen zweiten Code verbessert.
« Letzte Änderung: 15.06.2021, 12:12:15 von pinky »

Hat jemand eine Idee wie ich in dem folgenden Beispiel, den Wert der in der ersten Schleife definierten Variable "$a" in der zweiten Schleife zugänglich machen kann, um ihn dort per "echo $a" ausgeben zu können ?
Guten Morgen,
wie @Nessie und @pinky schon gezeigt haben kann man alles elegant in einer Schleife lösen.
Grundsätzlich stellt sich aber die Frage nach der systemweiten Verfügbarkeit von Variablen. Ich hätte da eine Lösung anzubieten und das geht so:
Erstelle eine Datei im Verzeichnis deines Scriptes mit folgendem Inhalt:
a=123Speicher sie unter dem Namen >meinvar.sh< und markiere sie als ausführbar.
In deinem Script verwendest du nun >source meinvar.sh< zur Ausgabe.
Das Script sieht dann wie folgt aus:
#!/bin/bash
source meinvar.sh
while true; do
    echo "Schleife 1 mit langem Takt, Ausgabe alle 10s,"
    echo $a "Hier Schleife 1" # funktionierende Ausgabe
    echo
    sleep 10
done &

while true; do
    echo "Schleife 2 mit kurzem Takt, Ausgabe alle 1s"
    echo $a  "Hier Schleife 2" # nicht funktionierende Ausgabe
    echo
    sleep 1
done
Ob das nun "Der Stein der Weisen ist" weiß ich nicht, aber es funktioniert...
Gruß
Wolfgang

Hehe, da möchte man gerne Race Conditions und Deadlocks kennenlernen.

Viel Spaß.   ;D

Hier mal zwei Beispiele mit einer Schleife - letzteres macht ungefähr, was du beschreibst:
Funktioniert bestens, nachdem ich den Schebeng von #!/usr/bin/bash auf #!/bin/bash geändert habe.
Danke.

Das hat mich jetzt auf eine neue Idee gebracht wie ich das als nächste Testvariante machen werde.

Ich werde mir die Systemzeit in Sekunden seit Linux Beginn holen:
aktuelle_zeit=date +%s
Dann fest legen in welcher Zeitspanne Zeitbereich das Script A oder B machen soll:
arbeits_dauer=28800 # sind 8h
freizeit_dauer=57600 # sind 16h
zeitbereich_arbeiten=$((aktuelle_zeit+arbeits_dauer)) # evt. Zahlenbereich zu groß
zeitbereich_freizeit=$((zeitbereich_arbeiten+ freizeit_dauer)) # evtl. Zahlenbereich zu groß

Mit der aktuellen Zeit vergleichen und dann A oder B machen:
#!/bin/bash
while true; do
      if (( xxxxxx <= yyyyyy )); then
        echo "Arbeitszeit"
    else
        echo "Freizeit"
    fi

    sleep 1
    echo
    echo
done

wait ...
« Letzte Änderung: 15.06.2021, 12:57:59 von John.Miller »

Funktioniert bestens, nachdem ich den Schebeng von #!/bin/bash auf #!/bin/bash geändert habe.
Siehe oben habe meinen Code mit Blick auf Antwort #4 verbessert.
Das hat mich jetzt auf eine neue Idee gebracht wie ich das als nächste Testvariante machen werde.
Mich auch. Endlos Schleife 2 horcht in eine pipe und empfängt dort Daten aus Schleife 1.
#!/bin/bash
if [ ! -p my_pipe ]; then
    mkfifo my_pipe
fi
for a in {0..3}; do
    sleep 10
    echo "Schleife 1 mit langem Takt, Ausgabe alle 10s, $a"
    echo $a >my_pipe
done &
while true; do
    read a <my_pipe
    echo "Empfange a, $a"
done