Jag förstår att -exec kan ta ett alternativ + för att efterlikna xargs. Finns det någon situation där du ”föredrar en form framför den andra?

Jag brukar personligen föredra den första formen, om bara för att undvika att använda ett rör. Jag tror säkert att utvecklarna av find måste” ha gjort lämpliga optimeringar. Är jag korrekt?

Svar

Du kanske vill kedja samtal för att hitta (en gång, när du fick veta att det är möjligt , vilket kan vara idag). Detta är naturligtvis bara möjligt så länge du stannar kvar. När du rör till xargs är det utanför räckvidden.

Litet exempel, två filer a.lst och b.lst:

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

Inget knep här – helt enkelt det faktum att båda innehåller ”fuddel” men bara en innehåller ”fiddel”.

Antag att vi inte visste det. Vi söker i en fil som matchar två villkor:

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 

Du kanske känner till syntaxen för grep eller ett annat program för att skicka båda strängarna som villkor, men att ” s inte poängen. Varje program som kan returnera true eller false, med en fil som argument, kan användas här – grep var bara ett populärt exempel.

Och notera, du kan följa hitta -exec med andra sökkommandon, som -ls eller -delete eller något liknande. Observera att det raderar inte bara rm (tar bort filer) utan rmdir (tar bort kataloger) också.

En sådan kedja läses som en OCH-kombination av kommandon, så länge som inte annat anges (nämligen med en -or -omkopplare (och parens (som behöver maskeras)).

Så du lämnar inte sökkedjan, vilket är en praktisk sak. Jag ser inte någon fördel med att använda -xargs, eftersom du måste vara försiktig med att skicka filerna, vilket är något du inte behöver göra – det hanterar automatiskt att skicka varje fil som ett enda argument för dig.

Om du tror att du behöver maskera för att hitta {} hängslen , besök gärna min fråga som ber om bevis. Mitt påstående är: Du behöver inte.

Kommentarer

  • Det här inlägget har öppnat mina ögon för ett nytt sätt att använda find. Tack så mycket!
  • ” Jag ser ’ t ser någon fördel med att använda -xargs ”. Vad ’ är -exec sättet att göra xargs -P4 så att tre av fyra kärnor inte ’ t förblir inaktiv?
  • @DamianYerrick: Avsluta kommandot -exec inte i ”; ” men med ett + (/ plustecken).

Svar

Säker piping av filnamn till xargs kräver att din find stöder -print0 alternativ och ditt xargs har motsvarande möjlighet att läsa det (--null eller -0). Annars filnamn med unprintab le tecken eller backslash eller citat eller blanksteg i namnet kan orsaka oväntat beteende. Å andra sidan finns find -exec {} + i POSIX find spec , så det är bärbart, och det är ungefär lika säkert som find -print0 | xargs -0, och definitivt säkrare än find | xargs. Jag rekommenderar aldrig att göra find | xargs utan -print0.

Kommentarer

  • Ett anmärkningsvärt undantag från portabiliteten för find … -exec … {} + är OpenBSD, som bara förvärvade den här funktionen med version 5.1 släppt 2012. Alla BSD har haft -print0 under flera år, till och med OpenBSD (även om det motstod den funktionen också ett tag). Solaris, å andra sidan, håller fast vid POSIX-funktioner så att du får -exec + och ingen -print0.
  • -print0 är en smärta och även om du kan argumentera xargs --delimiter "\n" isn ’ t ekvivalent, jag ’ har aldrig en gång använt det förra efter att ha upptäckt det senare .
  • Jag förstår inte ’ hur -0 är mer smärtsam än --delimiter "\n".
  • Förutom -0, GNU xargs behöver -r för att undvika att köra kommandot om ’ inte har någon ingång.
  • Ett annat problem med | xargs -r0 cmd är att cmd ’ s stdin påverkas (beroende på xargs -implementeringen, ’ s /dev/null eller röret.

Svar

Om du använder formuläret -exec ... ; för att komma undan semikolonet) kör du kommandot en gång per filnamn. Om du använder -print0 | xargs -0 kör du flera kommandon per filnamn. Du bör definitivt använda -exec + -form, som sätter flera filer på en enda kommandorad och är mycket snabbare när ett stort antal filer är inblandade.

Ett stort plus att använda xargs är möjligheten att köra flera kommandon parallellt med xargs -P. På flerkärniga system kan det ge stora tidsbesparingar.

Kommentarer

  • Du menade -P istället för -p. Kom ihåg att xargs -P inte finns i POSIX-standarden, medan find -exec {} + är, vilket är viktigt om du vill ha portabilitet.
  • @Alexios Du behöver inte ’ undgå plustecknet, eftersom det inte har någon speciell betydelse för skalet: find /tmp/ -exec ls "{}" + fungerar helt bra.
  • Corrent, naturligtvis. Jag ’ har rymt allt efter -exec så länge (jag ’ en masochist , Jag använder ’ inte ens citat för att undkomma {}, jag skriver alltid \{\}; don ’ t fråga), allt ser ut som om det måste undkommas nu.
  • @Alexios: Om du hittar ett exempel (förutom att vara en masochist) där maskering av hängslen är användbar, vänligen ange det som ett svar på min fråga här – afaik denna ledtråd är föråldrad och bara en relikt på manpage. Jag ’ Jag har aldrig sett ett exempel där find /tmp/ -exec ls {} + inte skulle fungera ’ t.
  • För mig är detta ett muskelminne som bildades under SunOS 4: s dagar. Eftersom jag ’ har gjort det i flera år misslyckades jag helt när bash började acceptera hängslen ordligt. Jag ’ är ganska säker på att åtminstone ett av de gamla skalen jag ’ har använt kastade vassa passningar om hängslen inte var ’ t slapp.

Svar

När det gäller prestanda trodde jag att -exec … + skulle helt enkelt vara bättre eftersom det är ett enda verktyg som gör allt arbete men en del av GNU findutils dokumentation säger att -exec … + kan vara mindre effektivt i vissa fall:

[hitta med -exec … +] kan vara mindre effektiv än vissa användningar av xargs; till exempel xargs tillåter att nya kommandorader byggs upp medan det tidigare kommandot fortfarande körs och låter dig ange ett antal kommandon som ska köras parallellt. Emellertid har find ... -exec ... + -konstruktionen fördelen med bred bärbarhet. GNU-sökverktyg stödde inte ‘-exec ... +’ förrän version 4.2.12 [januari 2005] ; en av anledningarna till detta är att den i alla fall redan hade -print0.

Jag var inte helt säker på vad det betydde så jag frågade i chatten var derobert förklarade det som:

find skulle förmodligen kunna fortsätta söka efter nästa sats filer medan -exec … + körs, men det fungerar inte.
find … | xargs … gör det, för då är sökningen en annan process och den håller kör tills pipbufferten fylls

(Formatering av mig.)

Så det finns det. Men om prestanda verkligen betyder något skulle du behöva göra realistisk benchmarking eller snarare till och med fråga dig själv om du ens skulle vilja använda skal för sådana fall.

Här på den här webbplatsen tycker jag att det är bättre att rekommendera människor att använd formuläret -exec … +, för bara för att det är enklare och av de skäl som nämns i de andra svaren här (t.ex. hantering av konstiga filnamn utan att behöva tänka mycket).

Lämna ett svar

Din e-postadress kommer inte publiceras. Obligatoriska fält är märkta *