Înțeleg că -exec poate lua o opțiune + pentru a imita comportamentul xargs. Există vreo situație în care ați prefera o formă decât cealaltă?

Personal am tendința de a prefera prima formă, chiar și numai pentru a evita utilizarea unei conducte. Cred că sunt cu siguranță dezvoltatorii find trebuie” să fi făcut optimizările corespunzătoare. Am dreptate?

Răspunde

S-ar putea să vrei să lansezi apeluri pentru a găsi (o dată, când ai aflat, că este posibil , care ar putea fi astăzi). Acest lucru este, desigur, posibil doar atâta timp cât rămâneți în căutare. Odată ce ați conectat la xargs, acesta nu mai intră în domeniul de aplicare.

Mic exemplu, două fișiere a.lst și b.lst:

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

Niciun truc aici – pur și simplu faptul că ambele conțin „fudel”, dar doar unul conține „fiddel”.

Să presupunem că nu știam asta. Căutăm un fișier care se potrivește cu 2 condiții:

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 

Ei bine, poate știți sintaxa pentru grep sau alt program pentru a trece ambele șiruri ca condiție, dar asta ” Nu este vorba. Fiecare program care poate returna adevărat sau fals, având în vedere un fișier ca argument, poate fi folosit aici – grep a fost doar un exemplu popular.

Și rețineți că puteți urma find -exec cu alte comenzi find, cum ar fi -ls sau -delete sau ceva similar. Rețineți că ștergerea nu numai că face rm (elimină fișierele), ci rmdir (elimină directoare).

Un astfel de lanț este citit ca o combinație ȘI de comenzi, atâta timp cât nu este specificat altfel (și anume cu un comutator -or (și parens (care au nevoie de mascare))).

Deci, nu părăsiți lanțul de găsire, ceea ce este un lucru la îndemână. Nu văd niciun avantaj în utilizarea -xargs, deoarece trebuie să fiți atenți la trecerea fișierelor, ceea ce nu este necesar să faceți – se ocupă automat de trecerea fiecărui fișier ca un singur argument pentru dvs.

Dacă credeți că aveți nevoie de mascare pentru descoperiri {} paranteze , nu ezitați să vizitați întrebarea mea care solicită dovezi. Afirmația mea este: Tu nu „t.

Comentarii

  • Această postare mi-a deschis ochii către un nou mod de utilizare a find. Mulțumesc!
  • ” Nu ‘ nu văd niciun avantaj în utilizarea -xargs „. Ce ‘ este -exec mod de a face xargs -P4 astfel încât trei din cele patru nuclee să nu ‘ să rămână inactiv?
  • @DamianYerrick: Terminați comanda -exec nu în „; ” dar cu semnul + (/ plus).

Răspuns

Conduirea în siguranță a numelor de fișiere către xargs necesită ca find să accepte -print0 opțiunea și xargs are opțiunea corespunzătoare pentru a o citi (--null sau -0). În caz contrar, numele fișierelor cu unprintab caracterele sau barele interioare sau ghilimelele sau spațiile albe din nume pot provoca un comportament neașteptat. Pe de altă parte, find -exec {} + se află în POSIX find spec , deci este portabil și este la fel de sigur ca find -print0 | xargs -0 și cu siguranță mai sigur decât find | xargs. Aș recomanda niciodată să nu find | xargs fără -print0.

Comentarii

  • O excepție notabilă de la portabilitatea find … -exec … {} + este OpenBSD, care a achiziționat această caracteristică numai cu versiunea 5.1 lansată în 2012. Toate BSD-urile au avut -print0 de câțiva ani, chiar și OpenBSD (deși a rezistat și pentru o perioadă de timp). Solaris, pe de altă parte, rămâne la caracteristicile POSIX, astfel încât să obțineți -exec + și nu -print0.
  • -print0 este o durere și deși puteți argumenta xargs --delimiter "\n" nu este ‘ t echivalent, nu am folosit niciodată prima dată după ce am descoperit-o .
  • Nu ‘ nu văd cum -0 este mai mult o durere decât --delimiter "\n".
  • Pe lângă -0, GNU xargs are nevoie de -r pentru a evita executarea comenzii dacă ‘ nu are intrări.
  • O altă problemă a | xargs -r0 cmd este că cmd ‘ s stdin este afectat (în funcție de implementarea xargs, este ‘ s /dev/null sau conducta.

Răspuns

Dacă utilizați formularul -exec ... ; (amintind pentru a scăpa de punct și virgulă), executați comanda o dată pe nume de fișier. Dacă utilizați -print0 | xargs -0, rulați mai multe comenzi pe nume de fișier. Ar trebui să utilizați cu siguranță , care pune mai multe fișiere într-o singură linie de comandă și este mult mai rapid atunci când este implicat un număr mare de fișiere.

Un mare plus al utilizării xargs este abilitatea de a rula mai multe comenzi în paralel folosind xargs -P. Pe sistemele multi-core, care pot oferi economii enorme de timp.

Comentarii

  • Ai vrut să spui -P în loc de -p. Rețineți că xargs -P nu se află în standardul POSIX, în timp ce find -exec {} + este, ceea ce este important dacă doriți portabilitate.
  • @Alexios Nu ‘ nu trebuie să scape de semnul plus, deoarece nu are o semnificație specială pentru shell: find /tmp/ -exec ls "{}" + funcționează foarte bine.
  • Bineînțeles, corect. ‘ scap de tot după -exec de atât de mult timp (eu ‘ ma masochist , Nu ‘ nici măcar nu folosesc ghilimele pentru a scăpa de {}, tastez întotdeauna \{\}; nu ‘ t ask), totul pare că trebuie scăpat acum.
  • @ Alexios: Dacă găsiți un exemplu (cu excepția faptului că sunteți masochist) în care mascarea parantezelor este utilă, vă rugăm să o furnizați ca răspuns la întrebarea mea aici – afaik acest indiciu este învechit și este doar o relict în pagina de manual. ‘ nu am văzut niciodată un exemplu în care find /tmp/ -exec ls {} + nu ar funcționa ‘.
  • Pentru mine, aceasta este memoria musculară formată în zilele SunOS 4. Întrucât ‘ o fac de ani de zile, nu am reușit să observ când bash a început să accepte parantezele text. ‘ sunt destul de sigur că cel puțin una dintre cochiliile vechi pe care ‘ le-am folosit aruncă sifonare dacă bretele nu erau ‘ t a scăpat.

Răspuns

În ceea ce privește performanța, am crezut că -exec … + ar fi pur și simplu mai bun, deoarece este „un singur instrument care face toate lucrările, dar o parte din documentația GNU findutil spune că -exec … + ar putea fi mai puțin eficient în unele cazuri:

[găsiți cu -exec … +] poate fi mai puțin eficient decât unele utilizări ale xargs; de exemplu xargs permite construirea de noi linii de comandă în timp ce comanda anterioară se execută în continuare și vă permite să specificați un număr de comenzi pentru a rula în paralel. Cu toate acestea, constructul find ... -exec ... + are avantajul unei portabilități largi. GNU findutils nu a acceptat ‘-exec ... +’ până la versiunea 4.2.12 [ianuarie 2005] ; unul dintre motivele pentru aceasta este că a avut deja acțiunea ‘-print0’ în orice caz.

Nu eram exact sigur ce înseamnă asta, așa că am întrebat în chat unde derobert a explicat-o astfel:

find probabil că ar putea continua să caute următorul lot de fișiere în timp ce -exec … + rulează, dar nu „t.
find … | xargs … funcționează, deoarece atunci găsirea este un proces diferit și se păstrează rulează până se umple bufferul de țeavă

(Formatare de către mine.)

Deci, există asta. Dar dacă performanța contează într-adevăr, ar trebui să faceți benchmarking realist sau, mai degrabă, chiar să vă întrebați dacă vreți să folosiți shell pentru astfel de cazuri.

Aici, pe acest site, cred că este mai bine să sfătuiți oamenii să utilizați formularul -exec … + ori de câte ori este posibil, deoarece doar pentru că este mai simplu și din motivele menționate în celelalte răspunsuri de aici (de exemplu, tratarea numelor de fișiere ciudate fără a fi nevoie să vă gândiți mult).

Lasă un răspuns

Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *