Jeg forstår, at -exec kan tage en + mulighed for at efterligne xargss opførsel. Er der nogen situation, hvor du “foretrækker en form frem for den anden?

Jeg personligt har en tendens til at foretrække den første form, hvis kun for at undgå at bruge et rør. Jeg regner med sikkerhed udviklerne af find skal” have foretaget de passende optimeringer. Er jeg korrekt?

Svar

Du vil muligvis kæde opkald for at finde (en gang, når du fik at vide, at det er muligt , som måske er i dag). Dette er naturligvis kun muligt, så længe du bliver i find. Når du rør til xargs, er den uden for omfanget.

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

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

Intet trick her – simpelthen det faktum, at begge indeholder “fuddel”, men kun en indeholder “fiddel”.

Antag, at vi ikke vidste det. Vi søger i en fil, der matcher 2 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 

Nå, måske kender du syntaksen for grep eller et andet program for at videregive begge strenge som betingelse, men at ” s ikke pointen. Hvert program, der kan returnere sandt eller falsk, givet en fil som argument, kan bruges her – grep var bare et populært eksempel.

Og bemærk, du kan følge find -exec med andre findkommandoer, som -ls eller -delete eller lignende. Bemærk, at sletning gør ikke kun rm (fjerner filer), men rmdir (fjerner mapper) også.

En sådan kæde læses som en AND-kombination af kommandoer, så længe ikke andet er angivet (nemlig med en -or switch (og parens (som skal maskeres)).

Så du forlader ikke find-kæden, hvilket er en praktisk ting. Jeg kan ikke se nogen fordel ved at bruge -xargs, da du skal være forsigtig med at videresende filerne, hvilket er noget, der ikke er nødvendigt at gøre – det håndterer automatisk at sende hver fil som et enkelt argument for dig.

Hvis du mener, at du har brug for maskering til fund {} seler , er du velkommen til at besøge mit spørgsmål, der beder om beviser. Min påstand er: Du behøver ikke.

Kommentarer

  • Dette indlæg har åbnet mine øjne for en ny måde at bruge . Mange tak!
  • ” Jeg ser ikke ‘ ikke nogen fordel ved at bruge -xargs “. Hvad ‘ er -exec måde at gøre så tre af fire kerner ikke ‘ ikke forbliver inaktiv?
  • @DamianYerrick: Afslut kommandoen -exec ikke i “; ” men med et + (/ plustegn).

Svar

Piping af filnavne sikkert til xargs kræver, at din find understøtter -print0 mulighed og din xargs har den tilsvarende mulighed for at læse den (--null eller -0). Ellers filnavne med unprintab le tegn eller tilbageslag eller anførselstegn eller mellemrum i navnet kan forårsage uventet opførsel. På den anden side er find -exec {} + i POSIX find spec , så det er bærbart, og det er omtrent lige så sikkert som find -print0 | xargs -0, og bestemt mere sikkert end find | xargs. Jeg vil anbefale aldrig at gøre find | xargs uden -print0.

Kommentarer

  • En bemærkelsesværdig undtagelse fra bærbarheden af find … -exec … {} + er OpenBSD, som kun erhvervede denne funktion med version 5.1 udgivet i 2012. Alle BSDer har haft -print0 i flere år, selv OpenBSD (selvom det også modstod denne funktion i et stykke tid). Solaris holder sig derimod til POSIX-funktioner, så du får -exec + og ingen -print0.
  • -print0 er en smerte, og selvom du kan argumentere xargs --delimiter "\n" isn ‘ t ækvivalent, jeg ‘ har aldrig brugt førstnævnte efter at have opdaget sidstnævnte .
  • Jeg kan ikke ‘ ikke se, hvordan -0 er mere smertefuld end --delimiter "\n".
  • Ud over -0, GNU xargs har brug for -r for at undgå at køre kommandoen, hvis der ‘ ikke er input.
  • Et andet problem med | xargs -r0 cmd er, at cmd ‘ s stdin påvirkes (afhængigt af xargs implementeringen er det ‘ s /dev/null eller røret.

Svar

Hvis du bruger formen -exec ... ; (husk for at undslippe semikolonet) kører du kommandoen en gang pr. filnavn. Hvis du bruger -print0 | xargs -0, kører du flere kommandoer pr. filnavn. Du bør bestemt bruge -exec + form, som placerer flere filer i en enkelt kommandolinje og er meget hurtigere, når et stort antal filer er involveret.

Et stort plus ved at bruge xargs er evnen til at køre flere kommandoer parallelt ved hjælp af xargs -P. På multi-core-systemer kan det give enorme tidsbesparelser.

Kommentarer

  • Du mente -P i stedet for -p. Husk, at xargs -P ikke er i POSIX-standarden, mens find -exec {} + er, hvilket er vigtigt, hvis du går efter bærbarhed.
  • @Alexios Du behøver ikke ‘ undslippe plustegnet, fordi det ikke har en særlig betydning for skallen: find /tmp/ -exec ls "{}" + fungerer fint.
  • Corrent, selvfølgelig. Jeg ‘ har været ved at undslippe alt efter -exec så længe (jeg ‘ en masochist , Jeg bruger ikke ‘ ikke engang citater for at undslippe {}, jeg skriver altid \{\}; don ‘ t spørg), alt ser ud som om det skal undslippes nu.
  • @Alexios: Hvis du finder et eksempel (bortset fra at være en masochist) hvor maskering af seler er nyttigt, bedes du give det som svar på mit spørgsmål her – afaik dette tip er forældet og kun en relik på manpage. Jeg ‘ har aldrig set et eksempel, hvor find /tmp/ -exec ls {} + ikke ville ‘ t arbejde.
  • For mig er dette muskelhukommelse dannet i dagene af SunOS 4. Da jeg ‘ har gjort det i årevis, har jeg fuldstændig undladt at bemærke, hvornår bash begyndte at acceptere seler ordret. Jeg ‘ er ret sikker på, at mindst en af de gamle skaller, jeg ‘ har brugt, kastede hissy fit, hvis selerne var ‘ t undslap.

Svar

Med hensyn til ydeevne troede jeg, at -exec … + ville simpelthen være bedre, fordi det “er et enkelt værktøj, der gør alt arbejdet, men , en del af GNU findutils dokumentation siger, at -exec … + kan være mindre effektiv i nogle tilfælde:

[find med -exec … +] kan være mindre effektiv end nogle anvendelser af xargs; for eksempel xargs tillader, at der bygges nye kommandolinjer, mens den forrige kommando stadig udføres, og giver dig mulighed for at specificere et antal kommandoer, der skal køres parallelt. find ... -exec ... + -konstruktionen har dog fordelen ved bred bærbarhed. GNU findutils understøttede ikke -exec ... + indtil version 4.2.12 [januar 2005] ; en af grundene til dette er, at den under alle omstændigheder allerede havde handlingen ‘-print0 .

Jeg var ikke helt sikker på, hvad det betød, så jeg spurgte i chatten, hvor derobert forklarede det som:

find sandsynligvis kunne fortsætte med at søge efter den næste batch af filer, mens -exec … + kører, men det gør det ikke.
find … | xargs … gør det, for så er fundet en anden proces, og det holder kører indtil rørbufferen fyldes op

(Formatering af mig.)

Så der er det. Men hvis ydeevne virkelig betyder noget, ville du være nødt til at foretage realistisk benchmarking eller rettere endda spørge dig selv, om du overhovedet vil bruge shell til sådanne tilfælde.

Her på dette site synes jeg det er bedre at råde folk til at brug formen -exec … +, når det er muligt, fordi bare fordi det er enklere og af de grunde, der er nævnt i de andre svar her (f.eks. håndtering af mærkelige filnavne uden at skulle tænke meget).

Skriv et svar

Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *