Verwendung des Exec-Befehls in Shell-Skripten

In diesem Handbuch wird der Befehl exec und seine Verwendung in Shell-Skripten ausführlicher erläutert.

Voraussetzungen:

Um die in diesem Handbuch gezeigten Schritte auszuführen, benötigen Sie die folgenden Komponenten:

  • Ein funktionsfähiges Linux-System. Erfahren Sie mehr über das Einrichten einer Ubuntu-VM mit VirtualBox.
  • Zugriff auf einen Nicht-Root-Benutzer mit Sudo-Berechtigung.
  • Ein geeigneter Texteditor. Zum Beispiel: Vim/NeoVim, Nano, Erhabener Text, VSCodiumusw.

Der Exec-Befehl

Der exec-Befehl ist kein eigenständiges Tool:

$ welcher Exec

Es handelt sich vielmehr um einen internen Befehl der Bash-Shell:

$ man exec

Wie aus der Beschreibung auf der Manpage hervorgeht, ersetzt exec bei Angabe eines Befehls die Shell durch diesen und erzeugt keinen zusätzlichen Prozess. Es stehen eine Handvoll Optionen zur Verfügung, die das Verhalten des Befehls exec ändern.

Grundlegende Verwendung

Standardmäßig erzeugt Bash bei jeder Ausführung eines Befehls eine Subshell und verzweigt den Befehl.

$ echo $$ && sleep 999

$ pstree -p

Hier gibt der Echo-Befehl die PID der aktuellen Shell aus. Die Bash-Shell (PID: 978) erzeugt einen neuen untergeordneten Prozess, der mit dem Befehl „sleep“ (PID: 8369) arbeitet.

Was wäre nun, wenn wir den Sleep-Befehl mit exec ausführen?

$ echo $$ && exec Sleep 999

$ pstree -p

Der übergeordnete Bash-Prozess wird durch den Befehl „sleep“ ersetzt. Bei erfolgreicher Ausführung erfolgt keine Rückkehr zur Shell. Stattdessen wird die Sitzung beendet.

Saubere Umwelt

Die Standard-Bash-Konfiguration enthält eine Reihe von Optimierungen und Umgebungsvariablen. In bestimmten Szenarien (z. B. beim Debuggen) möchten Sie Ihr Skript/Programm möglicherweise in einer sauberen Umgebung ausführen. Mit Hilfe von exec können wir anstelle der aktuellen eine saubere Shell-Instanz starten.

Verwenden Sie zunächst den Befehl printenv, um alle derzeit konfigurierten Umgebungsvariablen aufzulisten:

$ printenv

Verwenden Sie nun exec, um eine saubere Instanz zu starten:

$ exec -c bash

$ printenv

Eine andere Shell starten

Neben Bash und „sh“ stehen zahlreiche weitere Shell-Programme zur Verfügung, jedes mit seinen einzigartigen Vorteilen. Wenn ein Programm/Skript eine bestimmte Shell erfordert, können Sie mit exec die aktuelle Bash-Shell durch die gewünschte ersetzen.

Im folgenden Beispiel ersetzen wir Bash durch „sh“:

$ pstree -p

$ exec sh

$ pstree -p

Verwendung von Exec in Skripten

Nachdem die Grundlagen geklärt sind, können wir nun damit beginnen, exec in unseren Shell-Skripten zu verwenden.

Beispiel 1: Arbeiten mit verschiedenen Shells

Schauen Sie sich das folgende Skript an:

#!/bin/bash

echo $SHELL

echo „echo zsh erfolgreich gestartet“ > zsh.sh

exec zsh zsh.sh

Hier gibt der erste Echo-Befehl die aktuelle Shell aus. Standardmäßig sollte es Bash sein. Anschließend startet der Befehl exec „zsh“, um das Skript „zsh.sh“ auszuführen.

Führen Sie das folgende Skript aus:

$ ./test.sh

Beispiel 2: Überschreiben des vorhandenen Prozesses

Immer wenn ein Befehl/Programm aufgerufen wird, erzeugt Bash einen neuen Prozess. In den meisten Situationen ist das kein Grund zur Sorge. Wenn Sie jedoch mit einem System mit sehr begrenzten Ressourcen arbeiten (z. B. eingebettete Hardware), kann die Verwendung von exec zum Überschreiben des vorhandenen Prozesses im Speicher hilfreich sein.

Schauen Sie sich das folgende Skript an:

#!/bin/bash

pstree -p

exec pstree -p

Echo „Hallo Welt“

Hier zeigt der erste pstree-Befehl das ursprüngliche Layout des Prozessbaums. Sobald der Befehl exec ausgeführt wird, ersetzt der zweite Befehl pstree die laufende Shell. Der echo-Befehl in der letzten Zeile wurde nicht ausgeführt.

Führen Sie das folgende Skript aus:

$ ./test.sh

Da es Teil des Skripts war, kehren wir nach erfolgreicher Ausführung zur ursprünglichen Shell zurück.

Da der exec-Befehl die übergeordnete Shell durch einen anderen Befehl/ein anderes Programm ersetzt, wird jeglicher Code danach ungültig. Seien Sie vorsichtig, wenn Sie sie in Ihren Skripten verwenden.

Beispiel 3: Protokollierung

Die Bash-Shell bietet drei einzigartige Dateideskriptoren für jedes laufende Programm/Skript:

  • STDOUT (1): Standardausgabe, speichert die normale Ausgabe
  • STDERR (2): Standardfehler, speichert Fehlermeldungen
  • STDIN (0): Standardeingabe

Mit exec können wir diese Dateideskriptoren an einen anderen Speicherort umleiten, zum Beispiel: Protokolldateien. Es kann beim Debuggen und Protokollieren im Allgemeinen hilfreich sein.

Wenn Sie STDOUT und STDERR in eine Protokolldatei umleiten möchten, verwenden Sie im Allgemeinen den Umleitungsoperator:

$ echo $$ | tee test.log

$ monke 2>&1 | tee test.log

Diese Methode erfordert eine Umleitung an jedem Punkt, den Sie protokollieren möchten. Um dieses Problem zu lösen, können wir den Befehl exec verwenden, um eine permanente Umleitung für die Shell-Sitzung zu erstellen. Schauen Sie sich das folgende Beispiel an:

#!/bin/bash

> test.log

exec 1>>test.log

exec 2>&1

Echo „Hallo Welt“

falscher_Befehl

Hier erstellt die erste Zeile eine leere Protokolldatei. Der erste exec-Befehl richtet eine dauerhafte Umleitung von STDOUT zur Protokolldatei ein. Der zweite exec-Befehl leitet STDERR nach STDOUT um.

Bei diesem Setup werden alle Ausgaben und Fehlermeldungen in die Protokolldatei geschrieben:

$ ./test.sh

$ cat test.log

Was passiert, wenn das Skript kontinuierliche Protokolleinträge generiert?

#!/bin/bash

> test.log

exec 1>>test.log

exec 2>&1

zwar wahr

Tun

echo $RANDOM

Schlaf 5

Erledigt

Hier erstellen wir im ersten Teil eine permanente Umleitung von STDOUT und STDERR zu unserer Protokolldatei. Die Endlosschleife führt den Echo-Befehl aus, bis wir ihn mit „Strg + C“ zwangsweise schließen. Die Variable $RANDOM ist eine spezielle Variable, die bei jedem Zugriff eine zufällige Zeichenfolge zurückgibt.

Um den Aktualisierungsprotokolleintrag zu überprüfen, verwenden Sie den folgenden Tail-Befehl:

$ tail -f test.log

Beachten Sie, dass diese Umleitung nur für die Shell-Sitzung gilt.

Beispiel 4: Eingabe aus Datei

Ähnlich wie wir eine permanente STDOUT- und STDERR-Umleitung erstellt haben, können wir auch eine für STDIN erstellen. Da jedoch STDIN für die Eingabe verwendet wird, ist die Implementierung etwas anders.

Im folgenden Skript übernehmen wir STDIN aus einer Datei:

#!/bin/bash

echo „echo „Hallo Welt““ > Eingabe

exec < EingabeZeile_1 leseneval $line_1

Hier verwenden wir in der ersten Zeile echo, um den Inhalt der Datei „input_string“ mithilfe der Umleitung zu generieren. Der Befehl exec leitet den Inhalt von input_string an STDIN der aktuellen Shell-Sitzung um. Nachdem wir den String gelesen haben, verwenden wir eval, um den Inhalt von $line_1 als Shell-Code zu behandeln.

Führen Sie das folgende Skript aus:

$ ./test.sh

Abschluss

Wir haben über den exec-Befehl in Bash gesprochen. Wir haben auch die verschiedenen Möglichkeiten der Verwendung in Skripten vorgestellt. Wir haben demonstriert, wie man mit exec mit mehreren Shells arbeitet, speichereffiziente Skripts erstellt und die Dateideskriptoren umleitet.

Dies ist nur ein kleiner Teil dessen, was mit der Bash-Skripterstellung erreicht werden kann. Erfahren Sie mehr über Bash-Skripting in der Unterkategorie „Bash-Programmierung“.

Viel Spaß beim Rechnen!

Kommentar verfassen

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Nach oben scrollen