Ich habe manchmal über xargs
Nacht lange Jobs und es ist wirklich ärgerlich, am Morgen herauszufinden, dass ich xargs
irgendwo in der Mitte gestorben bin , zum Beispiel wegen eines Segmentierungsfehlers in einem einzigen Sonderfall, wie es diese Nacht passiert ist.
Wenn auch nur ein xargs
Kind getötet wird, werden keine Eingaben mehr verarbeitet:
Konsole 1:
[09:35:48] % seq 40 | xargs -i --max-procs=4 bash -c 'sleep 10; date +"%H:%M:%S {}";'
xargs: bash: terminated by signal 15
09:35:58 3
09:35:58 4
09:35:58 2
<Exit with code 125>
Konsole 2:
[09:35:54] kill 5601
Kann ich irgendwie verhindern xargs
, dass die Verarbeitung von Eingaben unterbrochen wird, sobald ein untergeordneter Prozess stirbt, und stattdessen die Verarbeitung fortsetzen?
xargs
Version 4.4.2 indebian wheezy
und es sieht so aus, als ob alles gut läuft, auch wenn ich einen bestimmtensleep
Prozess beende. Welche Version von verwendestxargs
du? Möglicherweise haben sie das Problem in der neuesten Version behoben.xargs ... bash -c '...;exit 0'
oder sogarxargs ... bash -c '... || echo erk'
parallel -j 1
eine mögliche Hack-Lösung ist.Antworten:
Nein, kannst du nicht. Aus den
xargs
Quellen bei savannah.gnu.org :Es gibt kein Flag um diese Prüfung oder um die Funktion, die sie aufruft. Es scheint mit max procs zu tun zu haben, was meiner Meinung nach Sinn macht: Wenn Sie max procs hoch genug einstellen, wird es nicht die Mühe machen zu prüfen, bis es das Limit erreicht, was Sie vielleicht nie erreichen werden.
Eine bessere Lösung für das, was Sie versuchen, könnte die Verwendung von GNU Make sein :
Dann:
wird den gleichen Effekt haben und Ihnen eine viel bessere Kontrolle geben.
quelle
Es scheint, dass einer der offensichtlichsten Umgangssprachen nur von anderen Vorschlägen angedeutet wird.
Das heißt, Sie können Folgendes verwenden:
um "Erfolg zu erzwingen".
Beachten Sie, dass dies im Sinne des Vorschlags von Lornix ist (nur nicht in so vielen Worten).
Da dies den tatsächlichen Status des Prozessabbruchs effektiv ignoriert, sollten Sie in Betracht ziehen, den Status des Unterprozesses für die Post-Mortem-Analyse zu speichern. Z.B:
Das
true
hier ist etwas überflüssig und daher könnte dies besser geschrieben werden als:Da würden wir wahrscheinlich gerne wissen, wann die 'fehlgeschlagene' Datei nicht angerührt werden konnte. Mit anderen Worten, wir ignorieren den Fehler nicht länger , wir nehmen ihn zur Kenntnis und fahren fort.
Und nachdem wir uns die rekursive Natur dieses Problems angesehen haben, sehen wir vielleicht genau, warum es mit xargs nicht einfach ist, Fehler zu ignorieren. Da dies keine gute Idee ist, sollten Sie stattdessen die Fehlerbehandlung in dem von Ihnen entwickelten Prozess verbessern. Ich glaube jedoch, dass dieser Begriff eher der "Unix-Philosophie" selbst innewohnt.
Schließlich ist es wohl auch das, worauf James Youngman mit einer Empfehlung anspielt
trap
, die vermutlich auf ähnliche Weise verwendet werden könnte. Das heißt, ignorieren Sie das Problem nicht ... fangen Sie es ein und behandeln Sie es, oder Sie wachen eines Tages auf und stellen fest, dass keines der Unterprogramme überhaupt erfolgreich war ;-)quelle
Verwendung
trap
:Wechseln Sie alternativ von der Shell in eine andere Sprache, in der Sie auch Signalhandler festlegen können.
Beachten Sie auch, dass
bash -c foo..
Sie nach dem Festlegen des Werts$0
(hier,fnord
) festlegen sollten, dass das erste von erzeugte Wortseq
nicht gegessen wird.quelle
Geben Sie einen weiteren Befehl ein, um das Signal aus dem sterbenden Programm zu "essen".
Ich habe zunächst Ihr Beispiel ausprobiert, um das Problem zu beweisen ... 'killall sleep' bricht den Schlafprozess ab, unterbricht bash und xargs wird beendet.
Als Test habe ich einen Befehl vom Typ 'run another command' zwischen xargs und bash eingefügt ... in diesem Fall '/ usr / bin / time'. Dieses Mal (kein Wortspiel) beendet killall sleep den Schlafprozess, aber die Xargs gehen weiter.
Sie würden die Ausgabe der Zeit nach / dev / null leiten, und dies würde genau das tun, wonach Sie suchen, ohne Ihren vorhandenen Prozess grundlegend umzuschreiben.
Ich stelle mir vor, wenn ich für einen Moment nachdenke, könnte ich mir ein anderes Programm einfallen lassen, um dasselbe zu tun, ohne das stderr-Chatter von '/ usr / bin / time'. Oder schreibe selbst einen, es ist nur eine Gabel (oder exec () - Ableitung).
Denken Sie daran, '/ usr / bin / time' zu verwenden, da ich nicht sicher bin, ob die eingebaute 'time' von bash dasselbe 'eating' des Signals bewirkt.
quelle
time
diesem Zweck wäre, dassenv
der Umgebung des ausgeführten Programms lediglich null oder mehr optionale Variablen hinzugefügt werden. Es gibt keine eigene Ausgabe aus, und der Rückgabecode des aufgerufenen Programms wird an das aufgerufene Programm zurückgegebenenv
.Weder für mich
time
nochenv
für mich gearbeitet (sie geben den Rückgabewert ihres Kinderprogramms weiter), also schrieb ichbliss
:dann
chmod u+x ~/bliss
und so ähnlich
find_or_similar | xargs ~/bliss fatally_dying_program.sh
quelle