Linux-Prozesswarteschleife

LinuxLinuxBeginner
Jetzt üben

💡 Dieser Artikel wurde von AI-Assistenten übersetzt. Um die englische Version anzuzeigen, können Sie hier klicken

Einführung

Linux-Prozesse sind grundlegende Bestandteile des Betriebssystems, die Programme ausführen und Aufgaben erledigen. Beim Entwickeln von Shell-Skripten ist es oft erforderlich, mehrere Prozesse gleichzeitig auszuführen und sicherzustellen, dass sie abgeschlossen sind, bevor mit den nachfolgenden Operationen fortgefahren wird.

In diesem Lab lernen Sie über den wait-Befehl in Linux-Shell-Skripten. Dieses leistungsstarke Werkzeug ermöglicht es Elternprozessen, die Ausführung anzuhalten, bis ihre Hintergrund-Kindprozesse abgeschlossen sind. Durch das Beherrschen von Techniken zum Warten auf Prozesse können Sie effizientere Skripte erstellen, die mehrere gleichzeitige Operationen richtig koordinieren.

Das Verständnis des Wartens auf Prozesse ist für die Systemadministration, Automatisierung und die Entwicklung robuster Shell-Skripte unerlässlich. Sie werden lernen, wie Sie Hintergrundprozesse starten, auf deren Abschluss warten und deren Exit-Status verarbeiten, um einen zuverlässigen Ausführungsfluss sicherzustellen.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL linux(("Linux")) -.-> linux/BasicFileOperationsGroup(["Basic File Operations"]) linux(("Linux")) -.-> linux/FileandDirectoryManagementGroup(["File and Directory Management"]) linux(("Linux")) -.-> linux/ProcessManagementandControlGroup(["Process Management and Control"]) linux(("Linux")) -.-> linux/VersionControlandTextEditorsGroup(["Version Control and Text Editors"]) linux/BasicFileOperationsGroup -.-> linux/chmod("Permission Modifying") linux/FileandDirectoryManagementGroup -.-> linux/cd("Directory Changing") linux/ProcessManagementandControlGroup -.-> linux/wait("Process Waiting") linux/VersionControlandTextEditorsGroup -.-> linux/nano("Simple Text Editing") subgraph Lab Skills linux/chmod -.-> lab-271433{{"Linux-Prozesswarteschleife"}} linux/cd -.-> lab-271433{{"Linux-Prozesswarteschleife"}} linux/wait -.-> lab-271433{{"Linux-Prozesswarteschleife"}} linux/nano -.-> lab-271433{{"Linux-Prozesswarteschleife"}} end

Grundlagen zu Linux-Prozessen und Hintergrundausführung

In diesem Schritt lernen Sie über Linux-Prozesse und wie Sie Befehle im Hintergrund mit dem &-Operator ausführen können.

Was sind Linux-Prozesse?

Ein Prozess in Linux ist eine Instanz eines laufenden Programms. Jeder Prozess hat eine eindeutige Prozess-ID (PID) und läuft unabhängig von anderen Prozessen. Wenn Sie einen Befehl im Terminal ausführen, starten Sie einen Prozess.

Ausführen von Prozessen im Hintergrund

Normalerweise müssen Sie, wenn Sie einen Befehl im Terminal ausführen, warten, bis er abgeschlossen ist, bevor Sie einen anderen Befehl ausführen können. Sie können jedoch einen Befehl im Hintergrund ausführen, indem Sie ein Ampersand & am Ende des Befehls anhängen.

Probieren wir dies aus:

  1. Navigieren Sie in Ihr Projektverzeichnis:

    cd ~/project
  2. Erstellen Sie ein einfaches Skript, das eine langlaufende Aufgabe simuliert:

    nano long_task.sh
  3. Fügen Sie dem Skript den folgenden Inhalt hinzu:

    #!/bin/bash
    echo "Starting long task with PID $$"
    sleep 5
    echo "Long task completed"
  4. Speichern Sie die Datei, indem Sie Strg+O drücken, dann Enter, und verlassen Sie den Editor mit Strg+X.

  5. Machen Sie das Skript ausführbar:

    chmod +x long_task.sh
  6. Führen Sie das Skript normal aus:

    ./long_task.sh

    Sie werden eine Ausgabe wie die folgende sehen:

    Starting long task with PID 1234
    Long task completed

    Beachten Sie, dass Sie warten mussten, bis das Skript abgeschlossen war, bevor Sie wieder den Befehlseingabeaufforderung zurückerhielten.

  7. Führen Sie nun das Skript im Hintergrund aus:

    ./long_task.sh &

    Sie werden eine Ausgabe wie die folgende sehen:

    [1] 1235
    Starting long task with PID 1235

    Die [1] ist die Job-Nummer, und 1235 ist die PID. Beachten Sie, dass Sie sofort wieder die Befehlseingabeaufforderung zurückerhalten.

  8. Nach etwa 5 Sekunden werden Sie sehen:

    Long task completed
    [1]+  Done                    ./long_task.sh

    Dies zeigt an, dass der Hintergrundprozess abgeschlossen ist.

Wenn Sie einen Befehl im Hintergrund ausführen, wartet die Shell nicht, bis er abgeschlossen ist, bevor Sie weitere Befehle eingeben können. Dies ist nützlich, um mehrere Aufgaben gleichzeitig auszuführen.

Verwenden des wait-Befehls zur Synchronisierung von Prozessen

In diesem Schritt lernen Sie, wie Sie den wait-Befehl verwenden können, um Prozesse zu synchronisieren und den Elternprozess so zu machen, dass er auf das Abschluss der Hintergrundprozesse wartet.

Was ist der wait-Befehl?

Der wait-Befehl wird in Shell-Skripten verwendet, um die Ausführung des Skripts anzuhalten, bis ein oder mehrere Hintergrundprozesse abgeschlossen sind. Dies ist besonders nützlich, wenn Sie sicherstellen müssen, dass bestimmte Aufgaben abgeschlossen sind, bevor Sie mit nachfolgenden Operationen fortfahren.

Verwenden von wait ohne Argumente

Wenn der wait-Befehl ohne Argumente verwendet wird, wartet er auf das Abschluss aller Hintergrundprozesse.

Erstellen wir ein Skript, das dies demonstriert:

  1. Navigieren Sie in Ihr Projektverzeichnis:

    cd ~/project
  2. Erstellen Sie ein neues Skript:

    nano wait_demo.sh
  3. Fügen Sie dem Skript den folgenden Inhalt hinzu:

    #!/bin/bash
    
    echo "Starting background tasks..."
    
    ## Start two background tasks
    ./long_task.sh &
    ./long_task.sh &
    
    echo "Waiting for all background tasks to complete..."
    wait
    echo "All background tasks have completed!"
  4. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X.

  5. Machen Sie das Skript ausführbar:

    chmod +x wait_demo.sh
  6. Führen Sie das Skript aus:

    ./wait_demo.sh

    Sie werden eine Ausgabe ähnlich der folgenden sehen:

    Starting background tasks...
    Starting long task with PID 1236
    Starting long task with PID 1237
    Waiting for all background tasks to complete...
    Long task completed
    Long task completed
    All background tasks have completed!

Beachten Sie, dass die Nachricht "All background tasks have completed!" erst erscheint, nachdem beide langlaufenden Aufgaben abgeschlossen sind. Dies zeigt, wie der wait-Befehl das Skript anhält, bis alle Hintergrundprozesse abgeschlossen sind.

Verwenden von wait mit einer bestimmten PID

Sie können wait auch verwenden, um auf einen bestimmten Prozess zu warten, indem Sie seine PID angeben:

  1. Erstellen Sie ein weiteres Skript:

    nano wait_pid_demo.sh
  2. Fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    
    echo "Starting background tasks..."
    
    ## Start two background tasks and capture their PIDs
    ./long_task.sh &
    pid1=$!
    
    ./long_task.sh &
    pid2=$!
    
    echo "First process PID: $pid1"
    echo "Second process PID: $pid2"
    
    echo "Waiting for the first task to complete..."
    wait $pid1
    echo "First task has completed!"
    
    echo "Waiting for the second task to complete..."
    wait $pid2
    echo "Second task has completed!"
  3. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X.

  4. Machen Sie das Skript ausführbar:

    chmod +x wait_pid_demo.sh
  5. Führen Sie das Skript aus:

    ./wait_pid_demo.sh

    Die Ausgabe wird zeigen, dass das Skript auf jeden Prozess individuell wartet.

Die Variable $! enthält die PID des zuletzt ausgeführten Hintergrundprozesses. Dies ermöglicht es Ihnen, die PID zu erfassen und später mit dem wait-Befehl zu verwenden.

Umgang mit dem Rückgabestatus von wait

In diesem Schritt lernen Sie, wie Sie den Rückgabestatus des wait-Befehls erfassen und verarbeiten können, der den Exit-Status der Hintergrundprozesse widerspiegelt.

Grundlagen zum Exit- und Rückgabestatus

In Linux gibt jeder Befehl beim Abschluss einen Exit-Status zurück. Ein Exit-Status von 0 zeigt normalerweise einen Erfolg an, während ein von Null abweichender Wert auf einen Fehler oder eine Art von Fehlschlag hinweist.

Der wait-Befehl gibt den Exit-Status des gewarteten Befehls zurück. Wenn auf mehrere Prozesse gewartet wird, gibt er den Exit-Status des letzten beendeten Prozesses zurück.

Erstellen wir Skripte, um dies zu demonstrieren:

  1. Navigieren Sie in Ihr Projektverzeichnis:

    cd ~/project
  2. Erstellen Sie ein Skript, das erfolgreich abläuft:

    nano success_task.sh
  3. Fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    echo "Starting success task"
    sleep 2
    echo "Success task completed successfully"
    exit 0 ## Exit with success status
  4. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X. Machen Sie es anschließend ausführbar:

    chmod +x success_task.sh
  5. Erstellen Sie ein Skript, das fehlschlägt:

    nano fail_task.sh
  6. Fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    echo "Starting fail task"
    sleep 3
    echo "Fail task encountered an error"
    exit 1 ## Exit with error status
  7. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X. Machen Sie es anschließend ausführbar:

    chmod +x fail_task.sh
  8. Erstellen Sie nun ein Skript, das den Status von wait erfasst:

    nano wait_status_demo.sh
  9. Fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    
    echo "Running a successful background task..."
    ./success_task.sh &
    wait
    
    wait_status=$?
    echo "Wait returned with status: $wait_status"
    
    if [ $wait_status -eq 0 ]; then
      echo "The background task succeeded!"
    else
      echo "The background task failed with status: $wait_status"
    fi
    
    echo ""
    echo "Running a failing background task..."
    ./fail_task.sh &
    wait
    
    wait_status=$?
    echo "Wait returned with status: $wait_status"
    
    if [ $wait_status -eq 0 ]; then
      echo "The background task succeeded!"
    else
      echo "The background task failed with status: $wait_status"
    fi
  10. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X. Machen Sie es anschließend ausführbar:

    chmod +x wait_status_demo.sh
  11. Führen Sie das Skript aus:

    ./wait_status_demo.sh

    Sie werden eine Ausgabe ähnlich der folgenden sehen:

    Running a successful background task...
    Starting success task
    Success task completed successfully
    Wait returned with status: 0
    The background task succeeded!
    
    Running a failing background task...
    Starting fail task
    Fail task encountered an error
    Wait returned with status: 1
    The background task failed with status: 1

Dies zeigt, wie Sie den Rückgabestatus des wait-Befehls nutzen können, um zu bestimmen, ob Hintergrundprozesse erfolgreich abgeschlossen wurden oder nicht. Dies ist für die Fehlerbehandlung in Shell-Skripten unerlässlich.

Abschluss einer praktischen Anwendung

In diesem letzten Schritt wenden Sie das Gelernte an, um ein komplexeres Skript zu erstellen, das einen Systemvorbereitungsprozess simuliert. Dieses Skript wird mehrere Hintergrundaufgaben koordinieren und sicherstellen, dass alle erfolgreich abgeschlossen sind, bevor es fortfährt.

Erstellen der Vorbereitungsskripte

Zunächst erstellen wir zwei Skripte, die verschiedene Vorbereitungsaufgaben simulieren:

  1. Navigieren Sie in Ihr Projektverzeichnis:

    cd ~/project
  2. Erstellen Sie das erste Vorbereitungsskript:

    nano decorate_hall.sh
  3. Fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    echo "Decorating the hall..."
    sleep 3
    echo "Hanging decorations..."
    sleep 2
    echo "Decoration complete."
    exit 0
  4. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X. Machen Sie es anschließend ausführbar:

    chmod +x decorate_hall.sh
  5. Erstellen Sie das zweite Vorbereitungsskript:

    nano cook_feast.sh
  6. Fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    echo "Preparing ingredients..."
    sleep 2
    echo "Cooking main dishes..."
    sleep 3
    echo "Preparing desserts..."
    sleep 1
    echo "Cooking complete."
    exit 0
  7. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X. Machen Sie es anschließend ausführbar:

    chmod +x cook_feast.sh

Erstellen des Hauptkoordinationsskripts

Jetzt erstellen wir das Hauptskript, das diese Vorbereitungsaufgaben koordinieren wird:

  1. Erstellen Sie das Hauptskript:

    nano prepare_feast.sh
  2. Fügen Sie den folgenden Inhalt hinzu:

    #!/bin/bash
    
    echo "=== Preparation Ceremony Started ==="
    echo "Starting all preparation tasks..."
    
    ## Start the preparations in the background
    ./decorate_hall.sh &
    decoration_pid=$!
    
    ./cook_feast.sh &
    cooking_pid=$!
    
    echo "All tasks started. Waiting for completion..."
    
    ## Wait for decoration to finish
    wait $decoration_pid
    decoration_status=$?
    
    if [ $decoration_status -eq 0 ]; then
      echo "Decoration completed successfully."
    else
      echo "Error: Decoration failed with status $decoration_status"
      exit 1
    fi
    
    ## Wait for cooking to finish
    wait $cooking_pid
    cooking_status=$?
    
    if [ $cooking_status -eq 0 ]; then
      echo "Cooking completed successfully."
    else
      echo "Error: Cooking failed with status $cooking_status"
      exit 1
    fi
    
    ## All preparations completed successfully
    echo "=== All preparations completed successfully! ==="
    echo "The ceremony can now begin."
    
    ## Create a verification file to indicate successful completion
    echo "decoration_status=$decoration_status" > preparation_results.txt
    echo "cooking_status=$cooking_status" >> preparation_results.txt
    echo "overall_status=0" >> preparation_results.txt
    
    exit 0
  3. Speichern Sie und verlassen Sie den Editor, indem Sie Strg+O drücken, dann Enter und schließlich Strg+X. Machen Sie es anschließend ausführbar:

    chmod +x prepare_feast.sh
  4. Führen Sie das Hauptskript aus:

    ./prepare_feast.sh

    Sie werden die Ausgabe aller parallel laufenden Vorbereitungsaufgaben sehen, und das Hauptskript wartet, bis jede Aufgabe abgeschlossen ist, bevor es den Gesamterfolg feststellt.

Verständnis des Skripts

Betrachten wir die wichtigsten Teile des Hauptskripts:

  • Wir starten jede Vorbereitungsaufgabe im Hintergrund mit &
  • Wir erfassen die PID jeder Aufgabe mit $!
  • Wir warten auf das Abschluss jeder Aufgabe mit wait $pid
  • Wir prüfen den Exit-Status jeder Aufgabe
  • Wir erstellen eine Verifikationsdatei mit den Ergebnissen

Dieser Ansatz ermöglicht es uns:

  1. Mehrere Aufgaben parallel auszuführen
  2. Den Erfolg/Misserfolg jeder Aufgabe zu überwachen
  3. Den gesamten Prozess abzubrechen, wenn eine einzelne Aufgabe fehlschlägt
  4. Eine Aufzeichnung der Ergebnisse zu erstellen

Dies ist ein gängiges Muster in Systemadministration und Automatisierungsskripten, bei denen mehrere Prozesse koordiniert und überwacht werden müssen.

Zusammenfassung

In diesem Lab haben Sie gelernt, wie Sie Prozesse in Linux effektiv verwalten und synchronisieren können, indem Sie den wait-Befehl verwenden. Diese wichtige Fähigkeit ermöglicht es Ihnen, ausgefeiltere Shell-Skripte zu erstellen, die mehrere gleichzeitige Operationen koordinieren können.

Die Schlüsselkonzepte, die Sie beherrscht haben, umfassen:

  • Ausführen von Prozessen im Hintergrund mit dem &-Operator
  • Verwenden des wait-Befehls, um die Ausführung anzuhalten, bis die Hintergrundprozesse abgeschlossen sind
  • Warten auf bestimmte Prozesse anhand ihrer PID
  • Erfassen und Verarbeiten des Rückgabestatus des wait-Befehls
  • Implementieren von Fehlerbehandlung für Hintergrundprozesse
  • Koordinieren mehrerer gleichzeitiger Aufgaben in einem praktischen Szenario

Diese Fähigkeiten sind grundlegend für die Systemadministration, Automatisierung und Shell-Skripting in Linux-Umgebungen. Durch die richtige Verwaltung der Prozesssynchronisierung können Sie effizientere Skripte erstellen, die die Parallelität nutzen, während sie den richtigen Ablauf abhängiger Operationen aufrechterhalten.

Egal, ob Sie Build-Systeme, Deploymentskripte oder Systemverwaltungstools entwickeln, die Fähigkeit, mehrere Prozesse zu koordinieren, ist eine essentielle Fähigkeit, die es Ihnen ermöglicht, leistungsfähigere und effizientere Lösungen zu schaffen.