web-dev-qa-db-fra.com

ls: terminé par le signal 13 lors de l'utilisation de xargs

J'utilise la commande suivante pour supprimer les quatre fichiers les plus volumineux d'un dossier:

find "/var/www/site1/" -maxdepth 1 -type f | xargs ls -1S | head -n 4 | xargs -d '\n' rm -f

Cela fonctionne bien, mais de temps en temps jette une erreur de tuyau cassé:

xargs: ls: terminated by signal 13
21
user1529918

J'ai rencontré un problème similaire et trouvé ce fil sur la recherche d'une réponse:

Le signal 13 signifie que quelque chose est écrit dans un tuyau où il n’ya plus rien de lu (voir http://people.cs.pitt.edu/~alanjawi/cs449/code/Shell/UnixSignals.htm ).

Le point ici est que la commande ls telle qu'elle est exécutée par xargs est toujours en train d'écrire en sortie lorsque la commande head suivante a déjà reçu toutes les entrées souhaitées et a fermé son canal d'entrée. Ainsi, il est prudent d’ignorer, mais c’est moche. Voir aussi la réponse acceptée dans https://superuser.com/questions/554855/how-can-i-fix-a-broken-pipe-error

25
planetmaker

Vous terminez volontairement votre programme avec head -n 4, ce qui crée le canal rompu, car vous l'avez terminé avant la fin de "l'appelant". Puisque cela est prévu par vous, vous pouvez ignorer l'erreur en la redirigeant vers /dev/null qui la supprime:

find "/var/www/site1/" -maxdepth 1 -type f | xargs ls -1S | head -n 4 | xargs -d '\n' rm -f 2>/dev/null

4
David Espart

J'ai eu la même erreur, "terminée par le signal 13", dans des circonstances différentes et d'autres réponses ici m'ont aidé à trouver une solution. J'aimerais développer la nature du problème:

corpy386 ~/gw/Release/5.1_v9/ClaimCenter $ find . -name '*.pcf' -not -name '*build*' | xargs grep -l ClaimSnapshotGeneralPanelSet | ( read f && echo $f && grep 'def=' $f )
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
xargs: grep: terminated by signal 13

Donc, voici la même erreur et je n’obtiendrais qu’une seule ligne de sortie lorsque je savais que de nombreux fichiers correspondaient à ce que je recherchais. Le problème était que xargs produisait plusieurs lignes de sortie et que read ne consommait qu'une seule ligne avant la fin. xargs essaie d'écrire le reste de ses résultats sur l'un des canaux, mais le destinataire est déjà parti et est rentré chez lui. Par conséquent, le signal 13: tuyau cassé.

Le correctif consistait à consommer toutes les sorties de xargs en bouclant - change read f && do_some_things (qui se lit une fois seulement) en while read f; do do_some_things; done.

corpy386 ~/gw/Release/5.1_v9/ClaimCenter $ **find . -name '*.pcf' -not -name '*build*' | xargs grep -l ClaimSnapshotGeneralPanelSet | while read f; do echo $f; grep 'def=' $f; done**
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.gl.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Pr.pcf
      def="ClaimSnapshotGeneralPRPanelSet(Claim, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Trav.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.wc.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/build/idea/classes/web/pcf/claim/snapshot/default/ClaimSnapshotLossDetailsScreen.default.pcf
      def="ClaimSnapshotGeneralPanelSet(Claim, SnapshotParam)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.auto.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.gl.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Pr.pcf
      def="ClaimSnapshotGeneralPRPanelSet(Claim, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.Trav.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotGeneralPanelSet.wc.pcf
          def="AddressSnapshotInputSet(Snapshot.LossLocation, Snapshot)"
./modules/configuration/config/web/pcf/claim/snapshot/default/ClaimSnapshotLossDetailsScreen.default.pcf
      def="ClaimSnapshotGeneralPanelSet(Claim, SnapshotParam)"

Ce n'est pas exactement la même chose que le script d'OP - ils voulaient une partie de l'entrée et la coupaient volontairement, je voulais tout le flux et le coupais par accident - mais la sémantique de Shell fonctionne de la même manière. Les programmes ont tendance à être écrits pour continuer à fonctionner jusqu'à ce qu'ils aient utilisé toutes leurs entrées plutôt que de tester pour voir si leur destinataire écoute toujours.

0
gws