Ich springe gerade in Unix aus einer anderen Welt und wollte wissen, ob
while true
do
/someperlscript.pl
done
Das Perl-Skript selbst verfügt intern über eine Ordner- / Dateiüberwachung, die ausgeführt wird, wenn Dateien am Zielspeicherort geändert werden.
Ist das ( while true
) eine gute Idee? Wenn nicht, was ist ein bevorzugter robuster Ansatz?
TIA
EDIT: Da dies einiges an Interesse geweckt zu haben scheint, ist hier das komplette Szenario. Das Perl-Skript selbst überwacht ein Verzeichnis mithilfe eines Dateiüberwachungsprogramms. Beim Empfang neuer Dateien (sie kommen über rsync an), nimmt es die neue und verarbeitet sie. Jetzt sind die eingehenden Dateien möglicherweise beschädigt (fragen Sie nicht nach .., die von einem Himbeer-Pi stammen), und manchmal ist der Prozess möglicherweise nicht in der Lage, damit umzugehen. Ich weiß nicht genau warum, da uns noch nicht alle Szenarien bekannt sind.
ABER - wenn der Prozess aus irgendeinem Grund fehlschlägt, soll er aktiv sein und die nächste Datei verarbeiten, da die nächste Datei nicht mit der vorherigen Datei zusammenhängt, die den Fehler verursacht haben könnte.
Normalerweise hätte ich irgendeine Art von catch all benutzt und den gesamten Code darum gewickelt, damit er NIEMALS abstürzt. War mir aber für Perl nicht sicher.
Soweit ich weiß, ist die Verwendung von Supervisord ein guter Ansatz dafür.
inotify
API überprüfen , um zu vermeiden, dass eine Besetztschleife darauf wartet, dass Dateien in Ihrem Zielverzeichnis geändert werden.Antworten:
Das hängt davon ab, wie schnell das Perl-Skript zurückkehrt. Wenn es schnell zurückkehrt, möchten Sie möglicherweise eine kleine Pause zwischen den Ausführungen einfügen, um eine CPU-Auslastung zu vermeiden, z.
Dies verhindert auch, dass die CPU überlastet wird, wenn das Skript nicht gefunden wird oder sofort abstürzt.
Die Schleife kann auch besser im Perl-Skript selbst implementiert werden, um diese Probleme zu vermeiden.
Bearbeiten:
Da Sie die Schleife geschrieben haben, besteht der einzige Zweck darin, das Perl-Skript neu zu starten, falls es abstürzt. Ein besserer Ansatz wäre, es als überwachten Dienst zu implementieren, aber der genaue Weg, dies zu tun, ist vom Betriebssystem abhängig. Beispiel: Solaris smf, Linux systemd oder ein Cron-basierter Neustarter.
quelle
while sleep 1; do ...
, um den wahren Anruf zu speichern.until ! sleep 1; do ...; done
speichert diesen integrierten Aufruf weiterhin, während das Skript sofort gestartet wird.sleep 1& /someperlscript.pl; wait
.until
Anweisung nie , ich habe sie mit einer hypothetischendo/until
Schleife verwechselt, die in der Shell nicht existiert.Die anderen Antworten zur Verwendung
inotify
sind korrekt, aber keine Antwort auf diese Frage.Verfahren Wacher wie
supervisord
,upstart
oderrunit
ist genau das Problem entwickelt , beobachten und dem Neustart eines Dienstes , wenn er abstürzt.Ihre Distribution wird wahrscheinlich mit einem eingebauten Prozess-Supervisor geliefert.
quelle
while true
eignet sich gut als Allzweckkonstruktion für "Endlosschleifen". Wie andere Antworten sagen, sollte der Körper der Schleife nicht leer sein oder aufgrund des Befehls innerhalb der Schleife, der nicht funktioniert, leer werden.Wenn Sie Linux verwenden, können Sie einen Befehl wie den folgenden verwenden
inotifywait
, wodurch diewhile
Schleife viel einfacher wird:Hier
inotifywait
wartet der Befehl, bis ein Dateisystemereignis auftritt (in diesem Beispiel, wenn Dateien in das Verzeichnis geschrieben werden). Zu diesem Zeitpunkt wird es erfolgreich beendet und der Rumpf der Schleife wird ausgeführt. Es geht dann wieder zum Warten zurück. Da derinotifywait
Befehl darauf wartet, dass im Verzeichnis etwas passiert, ist er weitaus effizienter, als das Verzeichnis fortlaufend abzufragen.quelle
Verschiebe while 1 in das Perl-Skript (folge dem @roaima-Vorschlag)
quelle
Wenn Ihr Perl-Skript die ganze Zeit ausgeführt werden soll, warum sollten Sie die while-Konstruktion verwenden? Wenn das Perl aufgrund eines schwerwiegenden Problems ausfällt, stürzt das neue Perl-Skript, das von while gestartet wurde, möglicherweise genauso hart ab. Immer wieder und so weiter.
Wenn Sie wirklich möchten, dass Ihr Perl neu gestartet wird, sollten Sie crontab und ein Skript in Betracht ziehen, das zuerst prüft, ob Instanzen ausgeführt werden. Auf diese Weise wird Ihr Skript auch nach einem Neustart gestartet.
quelle
Im Allgemeinen ist die Verwendung kein Problem,
while true
da es sich um einen winzigen Test handelt, der erst ausgeführt wird, nachdem das Perl-Skript beendet wurde. Beachten Sie, dass das Skript je nach verwendeter Linux / Unix-Variante beim Abmelden möglicherweise beendet wird. In diesem Fall sollten Sie die Schleife in einem Skript verwenden und mit aufrufennohup
und in den Hintergrund stellen, d. Hnohup myscript &
Wenn das Perl-Skript zu oft beendet wird und CPU-Last verursacht, ist diese Last für das Perl-Skript und nicht für das Perl-Skript verantwortlich
while true
.Siehe auch
man nohup
für weitere Einzelheiten.quelle
Wenn Sie einen Prozess verwalten möchten, suchen Sie möglicherweise einen Prozessmanager, um dies zu tun.
In vielen neueren Systemen können Sie systemd verwenden , um Ihre Prozesse zu überwachen (was einer der Vorteile von systemd gegenüber klassischen Init-Skripten ist). Wenn Ihre Distribution Ihrer Wahl nicht systemd verwendet, können Sie daemontools oder monit verwenden .
quelle
mon
ist eine einfache Alternative, wenn die lästige Gewalt von Monit und System Sie genauso stört wie mich.Die
while
Schleife ist wirklich keine gute Idee. Es gibt dort kein Entrinnen - es läuft nur für immer - statisch . Eine beliebige Anzahl von Dingen kann sich in der Umgebung ändern und wird nicht beeinträchtigt - und das kann schlimm sein.Wenn beispielsweise die für diese
while
Schleife verantwortliche ausführbare Shell-Datei aktualisiert wird, kann der Kernel den Speicherplatz für die alte Version erst freigeben , wenn das Skript beendet wird, da der Deskriptor so lange beibehalten werden muss, wie er ausgeführt wird. Und das gilt für alle Dateien, die die Shell möglicherweise aus irgendeinem Grund geöffnet hat, um die Schleife auszuführen. Sie werden alle von dieserwhile
Schleife so lange offengehalten, wie sie ausgeführt wird - für immer.Und wenn der Himmel es verbietet, dass irgendwo in der Shell ein Speicherleck auftritt, das diese Schleife ausführt - selbst in der kleinsten Minute -, wird sie einfach weiterlecken - statisch . Es wird ungeprüft erstellt und die einzige Möglichkeit besteht darin, es gewaltsam zu töten und es dann erneut zu starten, um später dasselbe zu tun.
Dies ist wirklich nicht die Art und Weise, wie Sie einen Hintergrundprozess einrichten sollten - zumindest meiner Meinung nach nicht. Stattdessen sollte es meines Erachtens einen Reset-Punkt geben - eine Aktualisierung des Skripts und seines Status. Am einfachsten geht das mit
exec
. Sie können den aktuellen Prozess durch einen neuen ersetzen - unter Beibehaltung der gleichen PID - und dennoch einen neuen Prozess ausführen.Wenn Ihr
perl
Skript beispielsweise true zurückgeben soll, nachdem eine Dateiänderung in einem überwachten Verzeichnis erfolgreich durchgeführt wurde:...oder etwas ähnliches. Etwas, das es den grundlegenden Maschinen hinter der Schleife ermöglicht, sich von Zeit zu Zeit zu aktualisieren.
quelle
Ich habe einige dieser Antworten positiv bewertet, habe aber instinktiv die wärmsten Gefühle für die Antwort von @ WalterA. Nun, ich habe es getan, bis ich meine eigene Antwort erstellt habe ...
Persönlich würde ich dazu tendieren, das Perl-Skript so zu aktualisieren, dass es einen beschreibenden Protokolleintrag über den Fehler schreibt und eine Warnung an einen Administrator sendet.
Wenn das Perl-Skript weiter ausgeführt werden soll und auf Änderungsereignisse vom Dateisystem gewartet wird, warum schlägt dies fehl?
Wenn es nicht fehlschlägt, warum möchten Sie es in ein Skript einbinden, um es unbegrenzt neu zu starten?
Wenn es ein Konfigurationsproblem oder eine defekte Abhängigkeit gibt, die zum Abbruch des Perl-Skripts führt, wird es wahrscheinlich nicht plötzlich funktionieren, wenn Sie es einfach immer wieder neu starten.
Sie kennen die Definition von Wahnsinn, oder? (Immer wieder dasselbe tun und ein anderes Ergebnis erwarten). Ich sage es nur. ;-)
quelle