Wie kann ich einen Systembefehl mit Alarm in Perl beenden?

8

Ich führe das folgende Code-Snippet unter Windows aus. Der Server beginnt nach dem Lesen vom Client kontinuierlich zu hören. Ich möchte diesen Befehl nach einer bestimmten Zeit beenden.

Wenn ich alarm () Funktionsaufruf innerhalb von main.pl verwende, dann beendet es das gesamte Perl-Programm ( Hier main.pl ), also habe ich diesen System -Befehl aufgerufen, indem ich ihn in eine separate Perl-Datei gestellt habe und diese Perl-Datei ( alarm.pl ) in der ursprünglichen Perl-Datei mit dem System -Befehl aufrufen.

Aber auf diese Weise konnte ich die Ausgabe dieses system() -Aufrufs weder in der ursprünglichen Perl-Datei noch in einer aufgerufenen Perl-Datei ausgeben.

Könnte mir bitte jemand sagen, wie ich einen system() -Aufruf beenden oder die Ausgabe auf die oben beschriebene Weise nutzen kann?

main.pl

%Vor%

alarm.pl

%Vor%

In beiden Fällen ist display.txt immer leer.

    
user285686 01.04.2010, 19:06
quelle

4 Antworten

15

Es gibt ein paar separate Probleme hier.

Erstens, um den Alarm davon abzuhalten, Ihr Skript zu löschen, müssen Sie mit dem ALRM-Signal umgehen. Weitere Informationen finden Sie in der Alarm -Dokumentation. Sie sollten dafür nicht zwei Skripte benötigen.

Zweitens erfasst das System keine Ausgabe. Du brauchst eine der Backtick-Varianten oder eine Pipe, wenn du das willst. Dafür gibt es schon Antworten auf Stackoverflow.

Drittens, wenn alarm.pl etwas in display.txt einfügt, verwirft es es in main.pl , wenn Sie die Datei erneut öffnen Datei im Schreibmodus. Sie müssen die Datei nur an einem Ort erstellen. Wenn Sie das zusätzliche Skript loswerden, haben Sie dieses Problem nicht.

Ich hatte kürzlich Probleme mit alarm und system , aber das Umschalten zu IPC :: System :: Simple hat das behoben.

Viel Glück,:

    
brian d foy 01.04.2010 19:19
quelle
8

Was zur Hölle habe ich gedacht? Sie benötigen für diese Aufgabe keinen Hintergrundprozess. Sie müssen nur dem Beispiel in der Funktion perldoc -f alarm folgen und Ihren zeitkritischen Code in eine% co_de einbinden % Block.

%Vor%

Innerhalb des Blocks eval können Sie Ihre Ausgabe auf reguläre Weise erfassen (mit Backticks oder eval oder qx() ). Wenn der Anruf jedoch abläuft, wird keine Ausgabe ausgegeben.

Wenn Sie die Ausgabe nicht benötigen (oder gegen eine Interprozesskommunikation zusammen hacken), besteht eine fast idiotensichere Alternative darin, den Alarm festzulegen und den readpipe -Aufruf in einem untergeordneten Prozess auszuführen.

%Vor%

system wird zurückgegeben, wenn der Befehl waitpid des Kindes beendet ist, oder , wenn der Alarm des Kindes ausgelöst wird und das Kind tötet. system enthält den Exit-Code des Systemaufrufs oder etwas anderes (142 auf meinem System) für ein nicht behandeltes SIGALRM oder 255, wenn Ihre SIGALRM-Behandlungsroutine $? aufruft.

    
mob 01.04.2010 20:44
quelle
2

Ich stoße auf ein ähnliches Problem, das erfordert:

  • Führe einen Systembefehl aus und erhalte seine Ausgabe
  • Timeout den Systembefehl nach x Sekunden
  • kill den Systembefehlsprozess und alle untergeordneten Prozesse

Nach viel lesen über Perl IPC und manuelle Gabel & amp; Exec, ich kam mit dieser Lösung heraus. Es wird als simuliertes "Backtick" -Unterprogramm implementiert.

%Vor%     
user454339 21.09.2010 19:25
quelle
-2

Kann "timeout -n" zum Umbrechen Ihrer Befehle verwenden, wenn dies bereits auf Ihrem System üblich ist.

    
hpavc 01.04.2010 23:10
quelle

Tags und Links