“ Túl hosszú az argumentumlista ”: Hogyan tudom kezelni, anélkül, hogy megváltoztatnám a parancsomat?

Amikor olyan parancsot futtatok, mint a ls */*/*/*/*.jpg, a hibát kapom

-bash: /bin/ls: Argument list too long 

Tudom, hogy miért történik ez: azért van, mert a parancs argumentumainak kernelkorlátja van. A szokásos tanács az általam használt parancs megváltoztatása, annak elkerülése érdekében, hogy ekkora helyet igényeljen az argumentumokhoz (pl. find és xargs).

Mi van, ha nem akarom megváltoztatni a parancsot? Mi van, ha továbbra is ugyanazt a parancsot akarom használni? Hogyan érhetem el, hogy a dolgok “egyszerűen működjenek” anélkül, hogy ezt a hibát észlelnék? Milyen megoldások állnak rendelkezésre?

megjegyzések

  • hasznos olvasmány: Bash GYIK 95 . A parancs megváltoztatása nélkül ' nem sokat tehet az újrafordítás mellett az argumentumlista maximális méretének növelése vagy a könyvtárstruktúra megváltoztatása érdekében, hogy kevesebb fájl legyen.
  • @ jw013 a Linux kernel verziója alapján lehetséges lehet az argumentumlista növelése – a változás változásáról lásd: unix.stackexchange.com/a/45161/8979 legújabb rendszerek.
  • @UlrichDangel, Yup, lehetséges! Lásd a válaszomat; a válaszom megmutatja, hogyan kell csinálni (L inux, elég friss kernellel).

Válasz

Linuxon a parancs maximális területe Az argumentumok a rendelkezésre álló veremterület 1/4-e. Tehát megoldás lehet a verem számára rendelkezésre álló hely növelése.

Rövid verzió: futtasson valami hasonlót:

ulimit -s 65536 

Hosszabb verzió : A verem számára rendelkezésre álló alapértelmezett hely nagysága körülbelül 8192 KB. A rendelkezésre álló hely mennyiségét a következőképpen láthatja:

$ ulimit -s 8192 

Válasszon nagyobb számot, és állítsa be a verem számára rendelkezésre álló helyet. Például, ha megpróbálja legfeljebb 65536 KB-ot engedélyezni a verem számára, futtassa ezt:

$ ulimit -s 65536 

Lehet, hogy el kell játszania, hogy ennek mekkora szüksége van próba-hiba módszerrel. Sok esetben ez egy gyors és piszkos megoldás, amely kiküszöböli a parancs módosításának szükségességét és a find, xargs stb. (bár tudom, hogy ennek más előnyei is vannak).

Úgy gondolom, hogy ez Linux-specifikus. Gyanítom, hogy valószínűleg nem fog segíteni más Unix operációs rendszereken (nincs tesztelve).

Megjegyzések

  • Így ellenőrizheti, hogy működött-e. : $ getconf ARG_MAX 2097152 $ ulimit -s 65535 $ getconf ARG_MAX 16776960
  • Ez azt jelenti, hogy ha korlátlanokká teszem a stackméretet a ulimit -s unlimited paranccsal, akkor a parancssor mérete korlátlan?

Válasz

A ls */*/*/*/*.jpg helyett próbálkozzon:

echo */*/*/*/*.jpg | xargs ls 

xargs (1) tudja, hogy mekkora az argumentumok maximális száma a rendszeren, és fel fogja bontani a szokásos bemenetet, hogy a megadott parancssort többször is meghívja, anélkül, hogy ennél a határnál több argumentumot használna, bármi is legyen az (a -n opció).

Tegyük fel például, hogy a korlát 3 argumentum, és öt fájlja van. Ebben az esetben xargs kétszer fogja végrehajtani a ls -t:

  1. ls 1.jpg 2.jpg 3.jpg
  2. ls 4.jpg 5.jpg

Ez gyakran tökéletesen megfelel, de nem mindig – például nem lehet támaszkodjon ls (1) az összes bejegyzés rendezésére az Ön számára, mert mindegyik különálló ls -hívás csak a (z) xargs által megadott bejegyzések részhalmazát rendezi.

Habár a korlátokat mások ajánlása szerint is megdöntheti, akkor is marad korlát – és valamikor a JPG-gyűjteményed újra kinövi. Fel kell készítenie a szkriptje (ke) t egy végtelen szám kezelésére …

Megjegyzések

  • Köszönjük az ötletet! Ez nem rossz megoldás. Két figyelmeztetés: 1. Ez megszakítja azokat a könyvtárakat és fájlneveket, amelyek nevében szóköz van, ezért ' nem tökéletes helyettesítője. 2. Ugyanezen problémába ütközik a következővel: Argument list too long, de echo esetén ls, olyan héjakon, ahol az echo nem shellbe épített parancs? (Lehet, hogy ez a ' nem probléma a legtöbb kagylóban, ezért talán ' ez lényegtelen.)
  • Igen , a fájlnevek speciális karakterei problémát jelentenek. A legjobb megoldás az, ha a find -t a -print0 predikátummal együtt használja – és a kimenetét átadja a xargs a -0 opcióval.Az echo egy beépített shell, és nem szenved a exec (3) parancssori korlátozásától.
  • Ez olyan parancsokkal működik, amelyek a változó argumentumot várják utolsó paraméterként, például ls esetén, de mit tegyek, ha mv sok fájl egyetlen könyvtárba, pl mv * destdir? Ha * túl sok args " hibát ad a " számára, akkor ' ne tegye xargs -et, hogy elsőként adja át az útvonalakat a mv -hez valahogy, vagy megtehetem?
  • Ellenőrizze a rendszeren a xargs kézikönyvet – például a FreeBSD-n a -J ezzel a feladattal. Ha az operációs rendszeren erre nincs mód, ' egyéni argumentumokat kell írnia az argumentumok átrendezéséhez. Valami ilyesmi: destdir=$1; shift; mv "$@" "$destdir". Ezután adja meg ezt az új parancsfájlt a következőhöz: xargs: .... | xargs newscript $destdir

Válasz

Ez a Linux Journal cikk 4 megoldást ad. Csak a negyedik megoldás nem jár a parancs megváltoztatásával:

A 4. módszer magában foglalja a rendszermagban kiosztott oldalak számának manuális növelését érvek. Ha megnézi az include / linux / binfmts.h fájlt, a következőket találja a tetején:

/* * MAX_ARG_PAGES defines the number of pages allocated for arguments * and envelope for the new program. 32 should suffice, this gives * a maximum env+arg of 128kB w/4KB pages! */ #define MAX_ARG_PAGES 32 

A memória növelése érdekében a parancssori argumentumoknak szentelve, egyszerűen meg kell adnia a MAX_ARG_PAGES értéket nagyobb számmal. Miután ezt a szerkesztést elmentettük, egyszerűen fordítsuk le, telepítsük és indítsuk újra az új kernelbe, ahogy általában tennénk.

Saját tesztrendszeremen sikerült megoldanom minden problémámat azzal, hogy ezt az értéket 64-re emeltem. tesztelés során a váltás óta egyetlen problémát sem tapasztaltam. Ez teljesen elvárt, mivel még ha MAX_ARG_PAGES 64-re van állítva, a lehető leghosszabb parancssor, amelyet elő tudtam állítani, csak 256 KB rendszermemóriát foglalna el – a mai rendszer hardveres szabványai szerint nem túl sok .

A 4. módszer előnyei egyértelműek. Most már egyszerűen futtathatja a parancsot, mint általában, és sikeresen teljes. A hátrányok ugyanolyan egyértelműek. Ha növeli a rendelkezésre álló memória mennyiségét parancssorba a rendelkezésre álló rendszermemória mennyiségén túl, létrehozhat egy DOS támadást a saját rendszerén, és összeomolást okozhat. Különösen a többfelhasználós rendszereken még egy kis növekedés is jelentős hatást gyakorolhat, mert minden felhasználó számára a további memória. Ezért mindig alaposan teszteljen a saját környezetében, mivel ez a legbiztonságosabb módszer annak megállapítására, hogy a 4. módszer megfelelő megoldás-e az Ön számára.

Egyetértek azzal, hogy a korlátozás komolyan idegesítő.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük