Jeg forstår at -exec kan ta et alternativ + for å etterligne oppførselen til xargs. Er det noen situasjon der du «foretrekker en form fremfor den andre?

Jeg pleier personlig å foretrekke den første formen, om ikke bare for å unngå å bruke et rør. Jeg regner med at utviklerne av find må» ha gjort de rette optimaliseringene. Stemmer jeg?

Svar

Det kan være lurt å ringe samtaler for å finne (en gang, når du fikk vite at det er mulig , som kan være i dag). Dette er selvfølgelig bare mulig så lenge du blir i finne. Når du rør til xargs, er den utenfor omfanget.

Lite eksempel, to filer a.lst og b.lst:

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

Ingen triks her – ganske enkelt det faktum at begge inneholder «fuddel», men bare en inneholder «fiddel».

Anta at vi ikke visste det. Vi søker i en fil som samsvarer med to betingelser:

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 

Vel, kanskje du vet syntaksen for grep eller et annet program for å passere begge strengene som betingelse, men at » s ikke poenget. Hvert program som kan returnere sant eller usant, gitt en fil som argument, kan brukes her – grep var bare et populært eksempel.

Og merk at du kan følge finn -exec med andre finnekommandoer, som -ls eller -delete eller noe lignende. Merk at sletting ikke bare gjør rm (fjerner filer), men rmdir (fjerner kataloger) også.

En slik kjede leses som en AND-kombinasjon av kommandoer, så lenge ikke annet er spesifisert (nemlig med en -or -bryter (og parens (som trenger maskering)).

Så du forlater ikke finnekjeden, noe som er en nyttig ting. Jeg ser ikke noen fordel ved å bruke -xargs, siden du må være forsiktig med å sende filene, noe som ikke trenger å gjøre – den håndterer automatisk å sende hver fil som et enkelt argument for deg.

Hvis du mener at du trenger maskering for funn {} seler , kan du gjerne besøke spørsmålet mitt som ber om bevis. Påstanden min er: Du har ikke t.

Kommentarer

  • Dette innlegget har åpnet øynene mine for en ny måte å bruke . Tusen takk!
  • » Jeg ser ikke ‘ t noen fordel ved å bruke -xargs «. Hva ‘ er -exec måte å gjøre slik at tre av fire kjerner ikke ‘ ikke holder seg inaktive?
  • @DamianYerrick: Avslutt -exec-kommandoen ikke i «; » men med et + (/ plusstegn).

Svar

Piping av filnavn til xargs krever at find støtter -print0 alternativet og xargs har det tilsvarende alternativet for å lese det (--null eller -0). Ellers filnavn med unprintab le tegn eller tilbakeslag eller anførselstegn eller mellomrom i navnet kan forårsake uventet oppførsel. På den annen side er find -exec {} + i POSIX find spesifikasjonen , så den er bærbar, og den er omtrent like trygg som find -print0 | xargs -0, og definitivt tryggere enn find | xargs. Jeg anbefaler aldri å gjøre find | xargs uten -print0.

Kommentarer

  • Et bemerkelsesverdig unntak fra portabiliteten til find … -exec … {} + er OpenBSD, som bare kjøpte denne funksjonen med versjon 5.1 utgitt i 2012. Alle BSD-er har hatt -print0 i flere år, til og med OpenBSD (selv om den motsto den funksjonen også en stund). Solaris holder seg derimot til POSIX-funksjoner, slik at du får -exec + og ingen -print0.
  • -print0 er en smerte, og selv om du kan argumentere xargs --delimiter "\n" isn ‘ t tilsvarer, jeg ‘ har aldri en gang brukt førstnevnte etter å ha oppdaget sistnevnte .
  • Jeg ser ikke ‘ t hvordan -0 er mer vondt enn --delimiter "\n".
  • I tillegg til -0, GNU xargs trenger -r for å unngå å kjøre kommandoen hvis ‘ ikke har noen inngang.
  • Et annet problem med | xargs -r0 cmd er at cmd ‘ s stdin påvirkes (avhengig av xargs implementeringen, er det ‘ s /dev/null eller røret.

Svar

Hvis du bruker skjemaet -exec ... ; for å unnslippe semikolonet) kjører du kommandoen en gang per filnavn. Hvis du bruker -print0 | xargs -0, kjører du flere kommandoer per filnavn. Du bør absolutt bruke -exec + -form, som setter flere filer på en enkelt kommandolinje og er mye raskere når et stort antall filer er involvert.

Et stort pluss å bruke xargs er muligheten til å kjøre flere kommandoer parallelt med xargs -P. På flerkjernesystemer kan det gi enorme tidsbesparelser.

Kommentarer

  • Du mente -P i stedet for -p. Husk at xargs -P ikke er i POSIX-standarden, mens find -exec {} + er, noe som er viktig hvis du ønsker portabilitet.
  • @Alexios Du trenger ikke ‘ for å unnslippe pluss-tegnet, fordi det ikke har en spesiell betydning for skallet: find /tmp/ -exec ls "{}" + fungerer helt fint.
  • Corrent, selvfølgelig. Jeg ‘ har rømt alt etter -exec så lenge (jeg ‘ en masochist , Jeg bruker ikke ‘ til og med anførselstegn for å unnslippe {}, jeg skriver alltid \{\}; ikke ‘ t spør), alt ser ut som om det må slippes unna nå.
  • @Alexios: Hvis du finner et eksempel (bortsett fra å være en masochist) hvor maskering av selene er nyttig, vennligst oppgi det som et svar på spørsmålet mitt her – avai dette hintet er utdatert og bare en relikvie på hjemmesiden. Jeg ‘ har aldri sett et eksempel der find /tmp/ -exec ls {} + ikke ville ‘ t fungerer.
  • For meg er dette muskelhukommelse dannet i dagene av SunOS 4. Siden jeg ‘ har gjort det i årevis, klarte jeg ikke å legge merke til når bash begynte å godta tannregulering ordrett. Jeg ‘ er ganske sikker på at minst en av de gamle skjellene jeg ‘ har brukt kastet hviskete pasninger hvis selene ikke var ‘ t slapp unna.

Svar

Når det gjelder ytelse, tenkte jeg at -exec … + ville ganske enkelt vært bedre fordi det er et enkelt verktøy som gjør alt arbeidet, men en del av GNU findutils dokumentasjon sier at -exec … + kan være mindre effektiv i noen tilfeller:

[finn med -exec … +] kan være mindre effektiv enn noen bruksområder av xargs; for eksempel xargs lar nye kommandolinjer bygges opp mens den forrige kommandoen fremdeles kjøres, og lar deg spesifisere et antall kommandoer som skal kjøres parallelt. Imidlertid har find ... -exec ... + -konstruksjonen fordelen av bred bærbarhet. GNU findutils støttet ikke ‘-exec ... +’ før versjon 4.2.12 [januar 2005] ; en av årsakene til dette er at den i alle fall allerede hadde handlingen ‘-print0 .

Jeg var ikke helt sikker på hva det betydde, så jeg spurte i chatten hvor derobert forklarte det som:

find kunne sannsynligvis fortsette å søke etter neste batch med filer mens -exec … + kjører, men det gjør det ikke.
find … | xargs … gjør det, for da er funnet en annen prosess, og den holder kjører til rørbufferen fylles opp

(Formatering av meg.)

Så det er det. Men hvis ytelse virkelig betyr noe, må du gjøre realistisk benchmarking eller heller spørre deg selv om du til og med vil bruke shell til slike tilfeller.

Her på dette nettstedet synes jeg det er bedre å råde folk til å bruk skjemaet -exec … + når det er mulig, bare fordi det er enklere og av årsakene som er nevnt i de andre svarene her (f.eks. håndtering av rare filnavn uten å måtte tenke mye).

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *