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
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
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
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.