Ymmärrän, että -exec
voi käyttää vaihtoehtoa +
jäljittelemään xargs
-käyttäytymistä. Onko tilanteita, joissa haluaisit yhden muodon toisen sijaan?
Minulla on tapana mieluummin ensimmäinen muoto, jos vain välttääksesi putken käyttöä. Luulen varmasti, että on suoritettava asianmukaiset optimoinnit. Olenko oikeassa?
Vastaa
Haluat ehkä ketjuttaa puhelut löytääksesi (kerran, kun opit, että se on mahdollista , mikä saattaa olla tänään). Tämä on tietysti mahdollista vain niin kauan kuin pysyt löytämässä. Kun lähetät xargs-sovelluksen sen ulkopuolelle.
Pieni esimerkki, kaksi tiedostoa a.lst ja b.lst:
cat a.lst fuddel.sh fiddel.sh cat b.lst fuddel.sh
Ei mitään temppua tässä – yksinkertaisesti se, että molemmat sisältävät ”fuddel”, mutta vain yksi sisältää ”fiddel”.
Oletetaan, ettemme tienneet sitä. Etsimme tiedostoa, joka vastaa kahta ehtoa:
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
No, ehkä tiedät grepin tai muun ohjelman syntaksin, joka välittää molemmat merkkijonot ehdoksi, mutta Ei ole asia. Tässä voidaan käyttää jokaista ohjelmaa, joka voi palauttaa arvon tosi tai epätosi, jos tiedosto on argumentti – grep oli vain suosittu esimerkki.
Huomaa, että voit seurata etsi -exec muiden hakukomentojen, kuten -ls tai -delete tai jotain vastaavaa. Huomaa, että poisto ei vain tee rm (poistaa tiedostoja), mutta rmdir (poistaa hakemistot).
Tällainen ketju luetaan JA-komennoina komennoista, ellei toisin ole määritelty (nimittäin -or
-kytkimellä (ja parens (jotka tarvitsevat naamiointia))).
Joten et jätä hakuketjua, mikä on kätevä asia. En näe mitään -xargs-tiedoston käytöstä, koska tiedostojen välittämisessä on oltava varovainen, mikä on jotain, jota löydön ei tarvitse tehdä – se käsittelee jokaisen tiedoston välittämisen automaattisesti yhtenä argumenttina sinulle.
Jos uskot tarvitsevasi peitettä löydöille {} olkaimet , käy rohkeasti kysymyksessäni, jossa pyydetään todisteita. Väitteeni on: Et. ”
Kommentit
- Tämä viesti on avannut silmäni uudelle tavalle käyttää
find
. Kiitos paljon! - ” En näe ’ en näe mitään etua käytettäessä -xargs ”. Mikä ’ on
-exec
-tapaxargs -P4
niin, että kolme neljästä ytimestä ei ’ pysy joutokäynnillä? - @DamianYerrick: Lopeta -exec -komento ei ”; ” mutta + (/ plus) -merkillä.
Vastaa
Tiedostojen nimien turvallinen siirtäminen xargs
edellyttää, että find
tukee -print0
-vaihtoehto ja xargs
-laitteellasi on vastaava mahdollisuus lukea se (--null
tai -0
). Muussa tapauksessa tiedostojen nimet on tulostettava merkit, taaksepäin viivat tai lainausmerkit tai välilyönti nimessä voivat aiheuttaa odottamatonta käyttäytymistä Toisaalta find -exec {} +
on POSIXissa find
spec , joten se on kannettava, ja se on suunnilleen yhtä turvallinen kuin find -print0 | xargs -0
ja ehdottomasti turvallisempi kuin find | xargs
. Suosittelen ei koskaan tekemistä find | xargs
ilman -print0
.
Kommentteja
vastaus
Jos käytät lomaketta -exec ... ;
(muistaa välttääksesi puolipisteen), suoritat komennon kerran tiedostonimeä kohti. Jos käytät -print0 | xargs -0
, suoritat useita komentoja tiedostonimeä kohti. Käytä ehdottomasti -exec +
-lomake, joka asettaa useita tiedostoja yhdelle komentoriville ja on paljon nopeampi, kun mukana on suuri määrä tiedostoja.
Suuri plus käyttämällä xargs
on kyky suorittaa useita komentoja rinnakkain xargs -P
-toiminnon avulla. Moniydinjärjestelmissä se voi säästää aikaa.
Kommentit
- Tarkoitit
-P
-p
-kohdan sijaan. Muista, ettäxargs -P
ei ole POSIX-standardissa, kun taasfind -exec {} +
on, mikä on tärkeää, jos aiot siirtyä. - @Alexios Sinun ei ’ ei tarvitse välttää plusmerkkiä, koska sillä ei ole erityistä merkitystä kuorelle:
find /tmp/ -exec ls "{}" +
toimii hienosti. - Korjaa tietysti. Olen ’ ollut paennut kaikesta
-exec
: n jälkeen niin kauan (I ’ ma masokisti , En ’ edes käytä lainausmerkkejä paeta{}
, kirjoitan aina\{\}
; älä ’ kysy), kaikki näyttää siltä, että siitä on nyt pakenemaan. - @Alexios: Jos löydät esimerkin (paitsi olemasta masokisti), jossa aaltosuojusten peittäminen on hyödyllistä, anna se vastauksena kysymykseeni täällä – afaik tämä vihje on vanhentunut ja vain reliktti manpagella. En ’ ole koskaan nähnyt esimerkkiä, jossa
find /tmp/ -exec ls {} +
ei toimisi ’. - Minulle tämä on lihasmuisti, joka on muodostunut SunOS 4: n päivinä. Koska olen ’ tehnyt sitä vuosia, en huomannut täysin, kun
bash
alkoi hyväksyä henkselit sanatarkasti. Olen ’ m melko varma, että ainakin yksi vanhoista kuorista, joita olen käyttänyt ’ olen käyttänyt, heitti hissy-sovituksia, jos henkselit katoavat ’ t pakenee.
Vastaus
Suorituskyvystä luulin, että -exec … +
olisi yksinkertaisesti parempi, koska se on yksi työkalu, joka tekee kaiken työn, mutta osa GNU findutilin dokumentaatiosta sanoo, että -exec … +
saattaa olla joissakin tapauksissa vähemmän tehokas:
[etsi
-exec … +
] voi olla vähemmän tehokas kuinxargs
; esimerkiksixargs
sallii uusien komentorivien rakentamisen edellisen komennon ollessa yhä käynnissä, ja voit määrittää useita komentoja suoritettavaksi rinnakkain.find ... -exec ... +
-konstruktilla on kuitenkin etuna laaja siirrettävyys. GNU findutils ei tue ‘-exec ... +
’ vasta versioon 4.2.12 [tammikuu 2005] ; yksi syy tähän on, että sillä oli joka tapauksessa jo toiminto ‘div div = = 077b99bba0″>
.
En ollut varma, mitä se tarkoitti, joten kysyin chatissa, missä derobert selitti sen seuraavasti:
find
todennäköisesti jatkaisi seuraavan tiedostoryhmän etsimistä, kun-exec … +
on käynnissä, mutta ei ”t.
find … | xargs …
, koska silloin haku on erilainen prosessi, ja se pitää käynnissä, kunnes putkipuskuri täyttyy
(Alustan itse.)
Joten siinä on. Mutta jos suorituskyvyllä on todella merkitystä, sinun on tehtävä realistinen vertailu tai pikemminkin jopa kysyttävä itseltäsi, haluatko edes käyttää shelliä tällaisissa tapauksissa.
Täällä tällä sivustolla mielestäni on parempi neuvoa ihmisiä käytä -exec … +
-lomaketta aina kun se on mahdollista, koska se on yksinkertaisempaa ja syistä, jotka mainitaan muissa täällä olevissa vastauksissa (esim. käsitellä outoja tiedostonimiä tarvitsematta ajatella paljon).
find … -exec … {} +
-sovelluksen siirrettävyyteen on OpenBSD, joka hankki tämän ominaisuuden vain versiolla 5.1, joka julkaistiin vuonna 2012. Kaikilla BSD-tiedostoilla on ollut-print0
useita vuosia, jopa OpenBSD (vaikka se vastusti tätä ominaisuutta myös jonkin aikaa). Solaris puolestaan pitää kiinni POSIX-ominaisuuksista, joten saat-exec +
ja ei-print0
.-print0
on tuska, ja vaikka voitkin väittääxargs --delimiter "\n"
ei ole ’ t -vastaavaa, en ’ ole koskaan käyttänyt ensimmäistä jälkimmäisen löytämisen jälkeen-0
on enemmän tuskaa kuin--delimiter "\n"
.-0
: n lisäksi GNUxargs
tarvitsee-r
välttää komennon suorittamista, jos ’ ei ole syötettä.| xargs -r0 cmd
-ongelma on, ettäcmd
’ s stdin vaikuttaa (riippuenxargs
-toteutuksesta, se ’ s/dev/null
tai putki.