Je fais parfois de longs xargs
travaux pendant la nuit et c'est vraiment ennuyeux de découvrir le matin qui est xargs
mort quelque part au milieu, par exemple à cause d'une erreur de segmentation dans un seul cas spécial, comme cela s'est produit cette nuit.
Si même un xargs
enfant est tué, il ne traite plus d'entrée:
Console 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>
Console 2:
[09:35:54] kill 5601
Puis-je empêcher en quelque sorte xargs
de s'arrêter pour traiter plus de données une fois qu'un processus enfant est mort et continuer à la place?
xargs
version 4.4.2debian wheezy
et il semble que tout fonctionne bien même si je tue unsleep
processus spécifique . Quelle versionxargs
utilisez-vous? peut-être qu'ils ont résolu le problème dans la dernière version.xargs ... bash -c '...;exit 0'
ou mêmexargs ... bash -c '... || echo erk'
parallel -j 1
c'est une solution de piratage possible.Réponses:
Non, tu ne peux pas. Des
xargs
sources à savannah.gnu.org :Il n'y a aucun indicateur autour de cette vérification ou autour de la fonction qui l'appelle. Cela semble être lié à max procs, ce qui, je suppose, a du sens: si vous définissez max procs suffisamment haut, cela ne vous dérangera pas de vérifier jusqu'à ce qu'il atteigne la limite, ce que vous pourriez ne jamais être.
Une meilleure solution pour ce que vous essayez de faire pourrait être d'utiliser GNU Make :
Ensuite:
aura le même effet et vous donnera un bien meilleur contrôle.
la source
Il semblerait que l'une des expressions les plus évidentes ne soit évoquée que par d'autres propositions.
Autrement dit, vous pouvez utiliser les éléments suivants:
afin de "forcer le succès".
Notez que cela va dans le sens de la proposition de lornix (mais pas en autant de mots).
Quoi qu'il en soit, étant donné que cela ignore effectivement l'état de sortie du processus réel, je m'assurerais que vous envisagiez d'enregistrer le statut de sous-processus pour l'analyse post mortem. Par exemple:
Le
true
ici est quelque peu redondant et cela peut donc être mieux écrit comme:Puisque nous aimerions probablement savoir quand le fichier «en échec» n'a pas pu être touché. Autrement dit, nous ne sommes plus ignorer l'échec, nous prenons note et continue.
Et, après avoir considéré la nature récursive de ce problème, nous voyons peut-être exactement pourquoi xargs ne facilite pas l'ignorance de l'échec. Parce que ce n'est jamais une bonne idée - vous devriez plutôt améliorer la gestion des erreurs dans le processus que vous développez. Je crois cependant que cette notion est plus inhérente à la "philosophie Unix" elle-même.
Enfin, je suppose que c'est aussi à cela que James Youngman fait allusion en recommandant
trap
, ce qui pourrait vraisemblablement être utilisé d'une manière similaire. Autrement dit, n'ignorez pas le problème ... piègez-le et gérez-le ou vous vous réveillez un jour et constatez qu'aucun des sous-programmes n'a réussi du tout ;-)la source
Utilisation
trap
:Vous pouvez également passer du shell à une autre langue dans laquelle vous pouvez également définir des gestionnaires de signaux.
Notez également qu'après
bash -c foo..
vous devez spécifier la valeur qui$0
devrait prendre (ici,fnord
) afin que le premier mot produit parseq
ne soit pas mangé.la source
Mettez une autre commande là-dedans pour «manger» le signal du programme mourant.
J'ai essayé votre exemple, initialement comme indiqué pour prouver le problème ... 'killall sleep' tue le processus de sommeil, interrompt bash et xargs se ferme.
Comme test, j'ai coincé une commande de type 'exécuter une autre commande' entre xargs et bash ... dans ce cas '/ usr / bin / time'. cette fois (sans jeu de mots), killall sleep tue le processus de sommeil, mais les xargs continuent.
Vous dirigeriez la sortie du temps vers / dev / null, et cela ferait exactement ce que vous recherchez sans une réécriture majeure de votre processus existant.
J'imagine que si je réfléchis un instant, je pourrais trouver un autre programme pour faire la même chose sans le bavardage stderr de '/ usr / bin / time'. Ou même en écrire un moi-même, c'est juste un 'fork' (ou un dérivé exec ()).
N'oubliez pas d'utiliser «/ usr / bin / time», car je ne suis pas sûr que le «temps» intégré de bash fera la même «consommation» du signal.
la source
time
cet effet seraitenv
, car il ne fait qu'ajouter zéro ou plusieurs variables facultatives à l'environnement du programme qu'il exécute. Il n'émet aucune sortie propre et le code retour du programme appelé sera retransmis à l'appelenv
.Ni
time
nienv
travaillé pour moi (ils transmettent la valeur de retour de leur programme enfant) alors j'ai écritbliss
:puis
chmod u+x ~/bliss
et quelque chose comme
find_or_similar | xargs ~/bliss fatally_dying_program.sh
la source