Verhindern, dass XARGS bei einem Fehler beendet wird

27

Laut Manpage wird xargs beendet, wenn eine der Ausführungszeilen mit einem Fehler von 255 beendet wird:

Wenn ein Aufruf des Befehls mit dem Status 255 beendet wird, stoppt xargs sofort, ohne weitere Eingaben zu lesen. In diesem Fall wird auf stderr eine Fehlermeldung ausgegeben.

Wie kann ich xargs dazu bringen, dies nicht zu tun?

Ich habe einen Stapeljob mit etwa 1500 Zeilen, den ich gleichzeitig mit 50 Zeilen ausführen möchte. Ich stellte fest, dass es immer an einer bestimmten Linie starb und den Job nicht erledigte. Nicht gut!

Eine noch bessere Frage, die Frage, was ich zu tun versuche, ist:

Wie kann ich ein 1500-Zeilen-Batch-Skript mit jeweils 50 Zeilen ausführen, damit der Job in der Mitte nicht beendet wird und die Ausgabe in einer Protokolldatei erfasst wird?

JDS
quelle

Antworten:

12

Sie können das Perl-Skript mit einem anderen einfachen Bash-Skript umschließen:

#!/bin/bash
real-command "$@" || exit 0

Dies ruft Real-Command auf und übergibt ihm alle Parameter, die Sie an dieses Fake-Command übergeben. Es gibt immer den Exit-Code 0 zurück (das heißt, es ist immer erfolgreich), und xargs hört nie damit auf.

user842313
quelle
24

Ähnlich zu larsksbeantworten, aber expliziter:

xargs sh -c "somecommand || true"
Filippo Vitale
quelle
benutze sh -cwors für mich!
Hukeping
9

Sie können Ihren xargs-Aufruf schreiben, um die Rückkehrcodes Ihrer Befehlszeilen zu maskieren. Bei so etwas wie dem folgenden xargswird es nie vorkommen, dass Exit-Codes von einem bestimmten Befehl zurückgegeben werden :

xargs sh -c "somecommand || :"
larsks
quelle
Ich habe eine gute Lösung gefunden: Stellen Sie sicher, dass die verarbeiteten Befehle nicht mit dem Status 255 beendet werden! Zusätzliche Details Der Befehl, der verarbeitet wird, ist ein Perl-Skript. Die Perl-Funktion die () wurde an mehreren Stellen verwendet, um den Vorgang zu beenden, wenn ein kritischer Fehler auftrat (z. B. konnte keine Verbindung zu einer Datenbank hergestellt werden). Die () wird jedoch immer mit dem Fehlerstatus 255 beendet. In diesem Fall bestand die Lösung darin, die () durch eine Kombination aus print und exit () zusammen mit einem vernünftigeren Fehlercode zu ersetzen (in diesem Fall hat "1" funktioniert).
JDS
6

Habe gerade eine unterhaltsame Antwort auf diese Frage gefunden, obwohl ihre Nützlichkeit von dem Befehl abhängt, den Sie ausführen möchten.

Wenn Sie xargs verwenden, um im Grunde genommen eine Liste von Befehlen zusammenzustellen, können Sie dieses Verhalten erzielen, indem Sie xargs anweisen, den Befehl zu wiederholen und anschließend an bash weiterzuleiten.

Wenn Sie beispielsweise versuchen, eine Liste von Dingen zu löschen, die möglicherweise vorhanden sind oder nicht:

# presume this will fail in a similar way to your command
cat things_to_delete | xargs -n1 delete_command_that_might_exit

# instead echo the commands and pipe to bash
cat things_to_delete | xargs -n1 echo delete_command_that_might_exit | bash

Dies funktioniert, weil xargs zunächst immer nur Echo aufruft, sodass keine Fehler angezeigt werden. Zweitens, weil Bashs Standardverhalten die Ausführung nach einer fehlgeschlagenen Anweisung fortsetzt.

Um genauer zu sein, ich habe dies verwendet, um eine Reihe alter Anwendungsversionen aus AWS ElasticBeanstalk zu entfernen:

aws elasticbeanstalk describe-application-versions --application-name myapp |\
jq -r '.ApplicationVersions | sort_by(.DateCreated) | .[0:-10] | .[].VersionLabel' |\
xargs -n1 \
  echo aws elasticbeanstalk delete-application-version \
       --delete-source-bundle --application-name myapp --version-label |\
bash
matschaffer
quelle
4

Folgende Bauarbeiten für mich:

ls | xargs -I % svn upgrade %

Auch wenn das Upgrade von svn auf einem Element fehlgeschlagen ist, wurde der Vorgang fortgesetzt

AndreyP
quelle
3

Wenn Sie xargsmit verwenden find, verwenden Sie stattdessen die -execOption von find:

find . -name '*.log' -exec somecommand {} \;
Roger Dahl
quelle
1
Hallo. Ich könnte das verwenden, aber die -exec-Option parallelisiert Operationen nicht wie mit Xargs können und tun
JDS
2
Vielen Dank - ich wusste nicht, dass xargsBefehle parallel ausgeführt werden können. Cool. Wenn Sie nur die Anzahl der Befehlsaufrufe minimieren möchten, -execgibt es einen +Parameter.
Roger Dahl