Chápu, že -exec může mít možnost + napodobit chování xargs. Existuje nějaká situace, kdy byste upřednostňovali jeden formulář před druhým?

Osobně mám tendenci upřednostňovat první formulář, i když jen proto, abych nepoužíval rouru. Určitě si myslím, že vývojáři find musí provést příslušnou optimalizaci. Mám pravdu?

Odpovědět

Možná budete chtít zřetězit hovory, abyste našli (jednou, když jste se dozvěděli, že je možné , což může být dnes). To je samozřejmě možné, pouze pokud zůstanete v nálezu. Jakmile se připojíte k xargs, je to mimo rozsah.

Malý příklad, dva soubory a.lst a b.lst:

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

Tady žádný trik – jednoduše skutečnost, že oba obsahují „fuddel“, ale pouze jeden obsahuje „fiddel“.

Předpokládejme, že jsme to nevěděli. Hledáme soubor, který odpovídá 2 podmínkám:

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 

Možná znáte syntaxi grepu nebo jiného programu, který předá oba řetězce jako podmínku, ale to “ nejde o smysl. Zde lze použít každý program, který může vracet true nebo false, a daný soubor jako argument – grep byl jen populární příklad.

A všimněte si, že můžete sledovat find -exec s dalšími vyhledávacími příkazy, například -ls nebo -delete nebo něco podobného. Pamatujte, že smazání nejenže odstraní rm (odstraní soubory), ale i rmdir (odebere adresáře).

Takový řetězec se čte jako kombinace příkazů AND, pokud není uvedeno jinak (konkrétně s přepínačem -or (a parens (které vyžadují maskování))).

Takže neopustíte řetězec hledání, což je užitečná věc. Nevidím žádnou výhodu v používání -xargs, protože při předávání souborů musíte být opatrní, což je něco, co najít nemusí – automaticky předává každý soubor jako jediný argument.

Pokud se domníváte, že potřebujete nějaké maskování pro nálezy {} závorky , neváhejte navštívit mou otázku, která žádá o důkazy. Moje tvrzení zní: „Don. T.

Komentáře

  • Tento příspěvek mi otevřel oči pro nový způsob používání find. Mnohokrát děkuji!
  • “ Nevidím ‚ při používání žádnou výhodu -xargs „. Jak ‚ je -exec způsob, jak xargs -P4 takže tři ze čtyř jader nezůstanou nečinná?
  • @DamianYerrick: Ukončit příkaz -exec není v „; “ ale se znaménkem + (/ plus).

Odpověď

Bezpečné pipování názvů souborů do xargs vyžaduje, aby váš find podporoval -print0 a vaše xargs má odpovídající možnost si ji přečíst (--null nebo -0). Jinak názvy souborů s unprintab Znaky nebo zpětná lomítka nebo uvozovky nebo mezery v názvu mohou způsobit neočekávané chování. Na druhou stranu find -exec {} + je ve POSIX find spec , takže je přenosný a je přibližně stejně bezpečný jako find -print0 | xargs -0 a rozhodně bezpečnější než find | xargs. Doporučuji nikdy nedělat find | xargs bez -print0.

Komentáře

  • Významnou výjimkou z přenositelnosti find … -exec … {} + je OpenBSD, které tuto funkci získalo až ve verzi 5.1 vydané v roce 2012. Všechny BSD měly -print0 několik let, dokonce i OpenBSD (i když se této funkci na chvíli také bránilo). Solaris se naopak drží funkcí POSIX, takže získáte -exec + a ne -print0.
  • -print0 je bolest, i když můžete argumentovat xargs --delimiter "\n" není ‚ t ekvivalent, ‚ jsem první nikdy nepoužil po objevení druhé .
  • Nechápu ‚, jak je -0 větší bolest než --delimiter "\n".
  • Kromě -0 GNU xargs potřebuje -r vyhnout se spuštění příkazu, pokud ‚ nemá žádný vstup.
  • Dalším problémem | xargs -r0 cmd je to, že cmd ‚ s stdin je ovlivněn (v závislosti na xargs implementaci, ‚ s /dev/null nebo kanálu.

Odpověď

Pokud použijete formulář -exec ... ; (pamatuji si uniknout středníkem), spustíte příkaz jednou pro každý název souboru. Pokud použijete -print0 | xargs -0, spustíte více příkazů na jeden název souboru. Měli byste určitě použít -exec + formulář, který umisťuje více souborů do jednoho příkazového řádku a je mnohem rychlejší, když se jedná o velký počet souborů.

Velkou výhodou použití xargs je schopnost paralelně spouštět více příkazů pomocí xargs -P. U vícejádrových systémů to může přinést obrovské časové úspory.

Komentáře

  • Měli jste na mysli -P místo -p. Pamatujte, že xargs -P není ve standardu POSIX, zatímco find -exec {} + ano, což je důležité, pokud se chystáte na přenositelnost.
  • @Alexios ‚ nemusíte uniknout znaménku plus, protože nemá pro shell zvláštní význam: find /tmp/ -exec ls "{}" + funguje dobře.
  • Samozřejmě, samozřejmě. ‚ Utekl jsem po -exec tak dlouho (jsem ‚ ma masochist , Ani ‚ nepoužívám uvozovky k úniku {}, vždy zadám \{\}; don ‚ t ask), vše vypadá, že teď musí uniknout.
  • @Alexios: Pokud najdete příklad (kromě toho, že jste masochista), kde maskování složených závorek je užitečné, uveďte jej prosím jako odpověď na moji otázku zde – afaik tato nápověda je zastaralá a pouze relikt na stránce. Nikdy jsem neviděl příklad, kde by find /tmp/ -exec ls {} + nefungoval ‚.
  • Pro mě je to svalová paměť utvářená ve dnech SunOS 4. Jelikož to dělám už roky, úplně jsem si nevšiml, když bash začal závorky přijímat doslovně. Jsem si ‚ docela jistý, že alespoň jeden ze starých granátů, které jsem použil ‚, použil hissy fit, pokud šle nebyly ‚ T uniklo.

Odpověď

Pokud jde o výkon, myslel jsem si, že -exec … + by prostě bylo lepší, protože je to jediný nástroj, který dělá veškerou práci, ale součást dokumentace GNU findutil říká, že -exec … + může být v některých případech méně efektivní:

[najít pomocí -exec … +] může být méně efektivní než některá použití xargs; například xargs umožňuje vytváření nových příkazových řádků, zatímco předchozí příkaz se stále spouští, a umožňuje zadat několik příkazů, které se mají spouštět paralelně. Konstrukce find ... -exec ... + má však výhodu široké přenositelnosti. GNU findutils nepodporovalo „-exec ... + do verze 4.2.12 [leden 2005] ; jedním z důvodů je, že v každém případě již akci „-print0 provedla.

Nebyl jsem si úplně jistý, co to znamená, tak jsem se zeptal v chatu, kde derobert vysvětlil to takto:

find pravděpodobně mohl pokračovat v hledání další dávky souborů, zatímco -exec … + běží, ale nedělá to.
find … | xargs … ano, protože pak je hledání jiný proces a udržuje běží, dokud se vyrovnávací paměť potrubí nezaplní

(Formátování mnou.)

Takže je to. Pokud ale na výkonu opravdu záleží, budete muset provést realistické srovnávací testy, nebo se dokonce sami sebe zeptat, zda byste vůbec chtěli použít shell pro takové případy.

Tady na tomto webu si myslím, že je lepší radit lidem, aby použijte -exec … + formulář, kdykoli je to možné, protože je to jednodušší a z důvodů zmíněných v dalších odpovědích zde (např. manipulace se zvláštními názvy souborů, aniž byste museli hodně přemýšlet).

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *