Kann Bash-Skript verwendet werden, um sequentielle und ereignisgesteuerte Aufgaben auszuführen?

0

Ich möchte wissen, wie ein Bash-Skript Aufgaben ausführen kann, die nacheinander ausgeführt werden müssen.

Hier ein Beispiel, ich möchte auf meinem CentOS VPS folgende Software installieren.

$ yum update
$ yum install libvpx-devel
$ sudo rpm -Uvh http://nginx.org/packages/centos/7/noarch/RPMS/nginx-release-centos-7-0.el7.ngx.noarch.rpm
$ yum install nginx
$ wget https //dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb - Chrome_stable
$ mkdir foo
$ mv Chrome_stable foo

Sie verstehen, ich habe Unmengen von Befehlen, die ich wöchentlich ausführen muss. Meine Frage ist also, dass einige Installationen fehlschlagen können und andere warten müssen, bis eine Installation abgeschlossen ist, damit die nächste fortgesetzt werden kann.

Gibt es also trotzdem die Möglichkeit, bash anzuweisen, zu warten, bis eine Installation / ein Download abgeschlossen ist, bevor der nächste Befehl ausgeführt wird, und vor dem Verschieben einer Installation zu überprüfen, ob die vorherige Installation erfolgreich war?

robue-a7119895
quelle

Antworten:

4

Sie müssen bash nicht anweisen, zu warten, wenn die von Ihnen ausgeführten Prozesse im Vordergrund ausgeführt werden (was alles, was Sie oben anzeigen, bewirkt) - es wird blockiert, darauf zu warten, dass sie beendet werden.

Sobald sie beendet sind, kann bash den Rückkehrcode untersuchen und sich basierend darauf anders verhalten. Der Rückgabewert des letzten Unterprozesses wird in $? Gespeichert. Variable:

#!/bin/bash

yum update

if [ $? -ne 0 ]; then
    echo "Sorry, yum update had non-zero exit code, why don't we stop here?"
    exit 1
fi

yum install libvpx-devel
...

Beachten Sie, dass die Unix-Konvention besagt, dass ein Rückkehrcode von 0 bedeutet, dass ein Prozess erfolgreich war, und ein Rückkehrcode von irgendetwas anderem bedeutet, dass es Probleme gab. Die Probleme können einfach (z. B. grep konnte die gesuchte Zeichenfolge nicht finden) oder komplexer sein.

Beachten Sie auch, dass Sie die Zeichen && und || verwenden können Bediener können den Rückkehrcode in einem Einzeiler nutzen:

yum update && echo "yum succeeded"

yum update || echo "yum failed"

Antwort auf @Contax-Fragen im Kommentar:

Die Verbindung zwischen "yum update" und "$?" ist, dass jedes Programm, das ausgeführt wird, einen Exit-Code hat, der an das Betriebssystem zurückgegeben wird. Der Standardwert ist 0 (Erfolg), wenn das Programm nichts angibt, er kann jedoch im Programm angegeben werden (z. B. setzt "exit 1" im obigen Skript den Exit-Code dieses Skripts auf 1. In C , "return (-1)" in der main () - Funktion bewirkt, dass das Programm einen Exit-Code von -1 hat.) Bash liest diesen Exit-Code automatisch und stopft ihn in $? für Ihren Gebrauch. Stellen Sie es sich einfach als Teil der Installation vor - es befindet sich hinter den Wänden und lässt alles funktionieren.

Wenn Sie viele Aufgaben ausführen müssen, wird dies mühsam. Das ist der Grund, warum 95% der Shell-Skripte keine Fehlerprüfung durchführen und auf spektakuläre Weise in die Luft jagen, wenn etwas schief geht :) Sie müssten if [ $? -ne 0 ]; thenfür jede Aufgabe eine Klausel erstellen . Wenn Sie wirklich abenteuerlustig wären, könnten Sie eine Möglichkeit finden, Ihre Ausführungen in eine Schleife zu packen und den Code erneut zu verwenden, aber das wäre wahrscheinlich mehr Mühe als es wert ist.

Die || Kurzform ist nützlich, um Kompromisse zwischen Code-Einfachheit und Fehlerprüfung einzugehen. Wie Sie bemerkt haben, ist das Schreiben einer ifKlausel für alles eine PITA, führt jedoch yum update || exit 1dazu, dass Ihr Skript schnell und leise in den Hintergrund tritt, wenn dieser Prozess fehlschlägt . Weniger freundlich, als sich die Zeit zu nehmen, Informationen auszudrucken und zu bereinigen, aber besser, als weiterhin Befehle auszuführen, die zum Scheitern verurteilt sind, weil ein früherer Schritt fehlgeschlagen ist.

Gowenfawr
quelle
Wow, danke, dass du mich umgehst. Aber ich sehe keine Verbindung zwischen yum updateund $?wird dies nicht zu einem Problem führen, wenn ich viele Aufgaben ausführen muss? oder muss ich if [ $? -ne 0 ]; thennach jeder aufgabe neu anlegen?
robue-a7119895
1
Eine andere Möglichkeit besteht darin, set -edie Befehle zu sagen und dann einfach aufzulisten (wie in der Frage dargestellt). set -eWeist die Shell an, das Skript zu beenden, wenn (wann) ein Befehl fehlschlägt (mit einem anderen Status als 0 beendet wird).
G-Man