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
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 argumenteraxargs --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
, GNUxargs
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 attcmd
’ 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 attxargs -P
inte finns i POSIX-standarden, medanfind -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 avxargs
; till exempelxargs
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 harfind ... -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).
find
. Tack så mycket!-exec
sättet att göraxargs -P4
så att tre av fyra kärnor inte ’ t förblir inaktiv?