Befehlszeilenbefehl zum automatischen Beenden eines Befehls nach einer bestimmten Zeit
Möchte ich automatisch zu töten, ein Befehl nach einer gewissen Zeit. Ich habe im Hinterkopf eine Schnittstelle wie diese:
% constrain 300 ./foo args
Die laufen würde "./foo" mit "args" aber automatisch zu töten, wenn es noch läuft nach 5 Minuten.
Könnte es sinnvoll sein, die Verallgemeinerung der Idee zu anderen Einschränkungen, wie autokilling ein Prozess, wenn es zu viel Speicher verwendet.
Gibt es bereits tools, die das tun, oder hat jemand geschrieben, so ein Ding?
HINZUGEFÜGT: Jonathan Lösung ist genau das, was ich im Sinn hatte, und es funktioniert wie ein Charme auf linux, aber ich kann nicht damit es funktioniert auf Mac OSX. Ich entledigte sich die SIGRTMIN, die können es kompilieren in Ordnung, aber das signal einfach nicht zugestellt bekommen, wird der Kind-Prozess. Wer weiß, wie diese Arbeit zu machen auf Mac?
[Hinzugefügt: Beachten Sie, dass ein update verfügbar ist von Jonathan, der arbeitet auf Mac und anderswo.]
InformationsquelleAutor der Frage dreeves | 2009-03-02
Du musst angemeldet sein, um einen Kommentar abzugeben.
Habe ich kam ziemlich spät zu dieser party, aber ich sehe nicht ein, meine Lieblings-trick aufgeführt die Antworten.
Unter *NIX, ein
alarm(2)
geerbt wird über eineexecve(2)
und SIGALRM fatal ist standardmäßig aktiviert. So können Sie oft einfach:installieren oder triviale C-wrapper zu tun, dass für Sie.
Vorteile Nur eine PID beteiligt ist, und der Mechanismus ist einfach. Sie töten nicht den falschen Prozess, wenn zum Beispiel
./foo.sh
verlassen "zu schnell" und die PID wurde wieder verwendet. Sie brauchen nicht mehrere shell Teilprozesse arbeiten im Konzert, die richtig getan werden, ist aber eher race-anfällig.Nachteile Die zeitgebundene Prozess nicht manipulieren kann, seinen Wecker (z.B.
alarm(2)
ualarm(2)
setitimer(2)
), da dies wahrscheinlich klar, die geerbt alarm. Natürlich, keiner kann es blockieren oder ignorieren SIGALRM, obwohl das gleiche kann gesagt werden von SIGINT, SIGTERM, etc. für einige andere Ansätze.Einige (sehr alt, glaube ich) - Systeme implementieren
sleep(2)
im Hinblick aufalarm(2)
und auch heute noch, einige Programmierer verwendenalarm(2)
als brutale internen timeout-Mechanismus für I/O und andere Operationen. In meiner Erfahrung, aber diese Technik ist für die überwiegende Mehrheit der Prozesse, die Sie wollen, um die Zeit zu begrenzen.InformationsquelleAutor der Antwort pilcrow
GNU Coreutils enthält die timeout Befehl, installiert standardmäßig auf vielen Systemen.
https://www.gnu.org/software/coreutils/manual/html_node/timeout-invocation.html
Beobachten
free -m
für eine minute, dann töten Sie, indem Sie einen BEGRIFF signal:InformationsquelleAutor der Antwort Roger Dahl
Vielleicht bin ich nicht die Frage zu verstehen, aber das klingt machbar direkt, zumindest in der bash:
Läuft der erste Befehl innerhalb der Klammern, für fünf Sekunden, und dann tötet es. Die gesamte operation synchron ausgeführt, d.h. Sie werden nicht in der Lage, Ihre shell verwenden, während es damit beschäftigt ist zu warten, für die slow-Befehl. Wenn das ist nicht, was Sie wollte, es sollte möglich sein, fügen Sie einen anderen &.
Den
$!
variable ist ein Bash-builtin, enthält die Prozess-ID des zuletzt subshell gestartet. Es ist wichtig, nicht haben & innerhalb der Klammer, es zu tun, die Art und Weise verliert die Prozess-ID.InformationsquelleAutor der Antwort unwind
Habe ich ein Programm namens
timeout
das bedeutet, dass - die in C geschrieben sind, ursprünglich im Jahr 1989, aber aktualisiert in regelmäßigen Abständen seit dann.Update: dieser code nicht kompilieren unter MacOS X, da SIGRTMIN ist nicht definiert, und es nicht-timeout beim laufen auf MacOS X, da die
signal()
Funktion dort wiederwait()
nachdem der alarm mal aus - das ist nicht die erforderliche Verhalten. Ich habe eine neue version vontimeout.c
die sich mit beiden Problemen (mitsigaction()
stattsignal()
). Wie vor, Kontaktieren Sie mich für ein 10K Gzip-tar-Datei mit dem Quellcode und eine manual-Seite (siehe mein Profil).Wenn Sie wollen, dass die 'offiziellen' code für 'stderr.h' und 'stderr.c', Kontaktieren Sie mich (siehe mein Profil).
InformationsquelleAutor der Antwort Jonathan Leffler
Gibt es auch ulimit, die verwendet werden können, zu beschränken und die Ausführung zur Verfügung stehenden Zeit auf sub-Prozesse.
Grenzen der Prozess um die 10 Sekunden CPU-Zeit.
Wirklich zu nutzen, zu begrenzen, einen neuen Prozess, anstatt den aktuellen Prozess, die Sie verwenden möchten, ein wrapper-Skript:
anderen-Befehl kann eine beliebige tool. Ich lief eine Java -, Python -, C-und Schema-Versionen der verschiedenen algorithmen zur Sortierung und Protokollierung, wie lang Sie nahm, während die Begrenzung der Ausführungszeit von 30 Sekunden. Eine Cocoa-Python-Anwendung generiert, die verschiedenen Befehlszeilen - einschließlich der Argumente - und zusammengestellt werden die Zeiten in eine CSV-Datei, aber es war wirklich nur Flaum auf der Oberseite der Befehl oben.
InformationsquelleAutor der Antwort Matthew Schinckel
Perl-one-liner, nur zum Spaß:
Diese prints " foo " für zehn Sekunden, dann auch mal aus. Ersetzen Sie '10' mit einer beliebigen Anzahl von Sekunden, und 'ja ' foo' mit einem beliebigen Befehl.
InformationsquelleAutor der Antwort vasi
Den timeout-Befehl von Ubuntu/Debian bei der Kompilierung von der Quelle bis zur Arbeit auf dem Mac. Darwin
10.4.*
http://packages.ubuntu.com/lucid/timeout
InformationsquelleAutor der Antwort sheki
Meine variation auf die perl-one-liner gibt Ihnen die exit-status ohne zu mucken mit fork() und wait() und ohne das Risiko der Tötung der falschen Prozess:
Grundsätzlich ist der fork() und wait() sind im inneren verborgen-system(). Die SIGALRM zugestellt wird der übergeordnete Prozess, der dann tötet sich und Ihr Kind durch senden von SIGTERM an den gesamten Prozess-Gruppe (-$$). In dem unwahrscheinlichen Fall, dass das Kind beendet und das Kind, das pid bekommt wiederverwendet vor dem kill() Auftritt, wird dies NICHT töten, den falschen Prozess, weil das neue Verfahren mit dem alten Kindes pid wird nicht in der gleichen Prozessgruppe des übergeordneten perl-Prozess.
Als zusätzlichen Vorteil, das Skript beendet sich mit dem, was ist wahrscheinlich den richtigen exit-status.
InformationsquelleAutor der Antwort bjaspan
Probieren Sie etwas wie:
Es hat den Nachteil, dass, wenn der Prozess " pid wiederverwendet wird innerhalb des timeout, kann es töten, den falschen Prozess. Dies ist höchst unwahrscheinlich, aber Sie können ab 20000+ - Prozesse pro Sekunde. Dies könnte behoben werden.
InformationsquelleAutor der Antwort fadedbee
Benutze ich "timelimit", die ein Paket im debian-repository.
http://devel.ringlet.net/sysutils/timelimit/
InformationsquelleAutor der Antwort maxy
Eine leichte Modifikation der perl-one-liner erhalten den exit-status Recht.
Grundsätzlich, exit ($? >> 8) leitet der exit-status des teilvorgangs. Ich habe gerade wählte 77 bei den exit-status für timeout.
InformationsquelleAutor der Antwort user143785
Wie über die Verwendung von dem tool erwarten?
InformationsquelleAutor der Antwort
reinen bash:
InformationsquelleAutor der Antwort yrn1
Den Wächter tötet die langsame Aufgabe, nach bestimmten timeout; das Skript wartet, bis die langsame task und beendet die watcher.
Beispiele:
InformationsquelleAutor der Antwort Dmitry
Gibt es nicht eine Möglichkeit zu einer bestimmten Zeit mit "an" um dies zu tun?
Scheint viel einfacher.
Wenn Sie nicht wissen, was die pid-Nummer wird, ich nehme an, es gibt einen Weg, um Skript, lese es mit ps aux und grep, aber nicht sicher, wie Sie Sie umsetzen.
Ihr Skript Lesen müsste die pid und weisen Sie es einer Variablen.
Ich bin nicht übermäßig talentiert, aber denke das ist machbar.
InformationsquelleAutor der Antwort tonybaldwin