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 omxargs -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
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 datxargs -P
niet in de POSIX-standaard staat, terwijlfind -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 vanxargs
;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. Defind ... -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).
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ërenxargs --delimiter "\n"
isn ‘ t equivalent, ik ‘ heb de eerste nooit gebruikt nadat ik de laatste had ontdekt .-0
meer vervelend is dan--delimiter "\n"
.-0
, GNUxargs
heeft-r
nodig om te voorkomen dat het commando wordt uitgevoerd als er ‘ geen invoer is.| xargs -r0 cmd
is datcmd
‘ s stdin wordt beïnvloed (afhankelijk van dexargs
implementatie, het ‘ s/dev/null
of de pipe.