Ik begrijp dat de -exec een + optie kan hebben om het gedrag van xargs na te bootsen. Is er een situatie waarin je “de ene vorm boven de andere zou verkiezen?

Ik heb persoonlijk de neiging om de eerste vorm te verkiezen, al was het maar om het gebruik van een pipe te vermijden. Ik denk zeker dat de ontwikkelaars van find moet” de juiste optimalisaties hebben uitgevoerd. Heb ik gelijk?

Answer

Misschien wil je kettingoproepen zoeken om te vinden (een keer, toen je hoorde, dat het mogelijk is , wat vandaag zou kunnen zijn). Dit is natuurlijk alleen mogelijk zolang je in find blijft. Als je eenmaal naar xargs hebt gepuist, valt het buiten bereik.

Klein voorbeeld, twee bestanden a.lst en b.lst:

cat a.lst fuddel.sh fiddel.sh cat b.lst fuddel.sh 

Geen truc hier – gewoon het feit dat beide “fuddel” bevatten, maar slechts één bevat “fiddel”.

Stel dat we dat niet wisten. We zoeken een bestand dat voldoet aan 2 voorwaarden:

find -exec grep -q fuddel {} ";" -exec grep -q fiddel {} ";" -ls 192097 4 -rw-r--r-- 1 stefan stefan 20 Jun 27 17:05 ./a.lst 

Misschien ken je de syntaxis voor grep of een ander programma om beide strings als voorwaarde door te geven, maar dat ” Het gaat er niet om. Elk programma dat true of false kan retourneren, gegeven een bestand als argument, kan hier worden gebruikt – grep was slechts een populair voorbeeld.

En let op, je kunt find -exec met andere zoekopdrachten, zoals -ls of -delete of iets dergelijks. Merk op dat verwijderen niet alleen rm (verwijdert bestanden), maar ook rmdir (verwijdert ook mappen).

Zon ketting wordt gelezen als een EN-combinatie van opdrachten, zolang niet anders gespecificeerd (namelijk met een -or schakelaar (en parens (die maskering nodig hebben))).

Dus je verlaat de vindketen niet, wat handig is. Ik zie geen enkel voordeel in het gebruik van -xargs, aangezien je voorzichtig moet zijn bij het doorgeven van de bestanden, wat iets wat je niet hoeft te doen – het behandelt automatisch het doorgeven van elk bestand als een enkel argument voor je.

Als je denkt dat je wat maskering nodig hebt voor vondsten {} accolades , ga dan gerust naar mijn vraag die om bewijs vraagt. Mijn bewering is: u don “t.

Reacties

  • Dit bericht heeft mijn ogen geopend voor een nieuwe manier om . Heel erg bedankt!
  • ” Ik zie geen ‘ enig voordeel in het gebruik van -xargs “. Wat is ‘ is de -exec manier om xargs -P4 zodat drie van de vier cores ‘ niet inactief blijven?
  • @DamianYerrick: Beëindig het -exec commando niet in “; ” maar met een + (/ plusteken).

Antwoord

Bestandsnamen veilig naar xargs sturen vereist dat uw find de -print0 optie en uw xargs heeft de overeenkomstige optie om het te lezen (--null of -0). Anders worden bestandsnamen met unprintab le-tekens of backslashes of aanhalingstekens of witruimte in de naam kunnen onverwacht gedrag veroorzaken. Aan de andere kant bevindt find -exec {} + zich in de POSIX find specificatie , dus het is draagbaar, en het is ongeveer net zo veilig als find -print0 | xargs -0, en zeker veiliger dan find | xargs. Ik “zou aanraden nooit find | xargs te doen zonder -print0.

Reacties

  • Een opmerkelijke uitzondering op de overdraagbaarheid van find … -exec … {} + is OpenBSD, dat deze functie pas heeft verworven met versie 5.1 die in 2012 werd uitgebracht. Alle BSDs hebben -print0 voor meerdere jaren, zelfs OpenBSD (hoewel het zich ook een tijdje tegen die functie verzette). Solaris daarentegen houdt vast aan POSIX-functies, dus je krijgt -exec + en geen -print0.
  • -print0 is lastig en hoewel je kunt discussiëren xargs --delimiter "\n" isn ‘ t equivalent, ik ‘ heb de eerste nooit gebruikt nadat ik de laatste had ontdekt .
  • Ik ‘ zie niet in hoe -0 meer vervelend is dan --delimiter "\n".
  • Naast -0, GNU xargs heeft -r nodig om te voorkomen dat het commando wordt uitgevoerd als er ‘ geen invoer is.
  • Een ander probleem van | xargs -r0 cmd is dat cmd ‘ s stdin wordt beïnvloed (afhankelijk van de xargs implementatie, het ‘ s /dev/null of de pipe.

Antwoord

Als u het -exec ... ; formulier gebruikt (onthoud om aan de puntkomma te ontsnappen), “voer je het commando één keer per bestandsnaam uit. Als je -print0 | xargs -0 gebruikt, voer je meerdere commandos per bestandsnaam uit. Je moet zeker de formulier, dat meerdere bestanden op één opdrachtregel plaatst en veel sneller is wanneer het een groot aantal bestanden betreft.

Een groot voordeel van het gebruik van xargs is de mogelijkheid om meerdere commandos parallel uit te voeren met xargs -P. Op multi-core systemen kan dat een enorme tijdwinst opleveren.

Opmerkingen

  • Je bedoelde -P in plaats van -p. Houd er rekening mee dat xargs -P niet in de POSIX-standaard staat, terwijl find -exec {} + dat wel is, wat belangrijk is als je voor draagbaarheid gaat.
  • @Alexios Je hoeft ‘ niet te ontsnappen aan het plusteken, omdat het geen speciale betekenis heeft voor de shell: find /tmp/ -exec ls "{}" + werkt prima.
  • Corrent, natuurlijk. Ik ‘ ontsnap al zo lang aan alles na de -exec (ik ‘ ma masochist , Ik ‘ gebruik zelfs geen aanhalingstekens om te ontsnappen aan {}, ik typ altijd \{\}; don ‘ t ask), ziet alles eruit alsof het nu moet worden ontsnapt.
  • @Alexios: als je een voorbeeld vindt (behalve dat je een masochist bent) waar de het maskeren van de accolades is handig, geef het als antwoord op mijn vraag hier – afaik is deze hint verouderd en slechts een relict in de manpagina. Ik ‘ heb nog nooit een voorbeeld gezien waarin find /tmp/ -exec ls {} + niet ‘ zou werken.
  • Voor mij is dit spiergeheugen gevormd in de dagen van SunOS 4. Aangezien ik ‘ dit al jaren doe, merkte ik helemaal niet dat bash begon de accolades woordelijk te accepteren. Ik ‘ ben er vrij zeker van dat ten minste een van de oude schelpen die ik ‘ heb gebruikt, sissende bewegingen heeft gemaakt als de beugels t ontsnapt.

Antwoord

Wat betreft prestaties dacht ik dat -exec … + zou gewoon beter zijn omdat het “een enkele tool is die al het werk doet, maar een deel van de GNU findutil” s documentatie zegt dat -exec … + kan in sommige gevallen minder efficiënt zijn:

[zoek met -exec … +] kan minder efficiënt zijn dan sommige toepassingen van xargs; xargs staat bijvoorbeeld toe dat nieuwe opdrachtregels worden opgebouwd terwijl de vorige opdracht nog wordt uitgevoerd, en staat u toe om een aantal opdrachten te specificeren die parallel moeten worden uitgevoerd. De find ... -exec ... + -constructie heeft echter het voordeel van brede draagbaarheid. GNU findutils ondersteunde ‘-exec ... +’ niet tot versie 4.2.12 [januari 2005] ; een van de redenen hiervoor is dat het in ieder geval al de ‘-print0’ -actie had.

Ik wist niet precies wat dat betekende, dus vroeg ik in de chat waar derobert legde het uit als:

find zou waarschijnlijk kunnen doorgaan met zoeken naar de volgende batch bestanden terwijl de -exec … + is actief, maar “t. niet.
find … | xargs … wel, want dan is de zoekopdracht een ander proces en blijft het loopt totdat de pijpbuffer vol is

(Formatteren door mij.)

Dus dat is er. Maar als de prestaties er echt toe doen, zou je realistische benchmarking moeten doen of liever jezelf afvragen of je zelfs shell zou willen gebruiken voor dergelijke gevallen.

Hier op deze site denk ik dat het beter is om mensen te adviseren om gebruik waar mogelijk het -exec … + -formulier omdat het simpeler is en om de redenen die in de andere antwoorden hier worden genoemd (bv. omgaan met vreemde bestandsnamen zonder veel na te denken).

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *