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:
-
ls 1.jpg 2.jpg 3.jpg
-
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
, deecho
eseténls
, olyan héjakon, ahol azecho
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 axargs
a-0
opcióval.Azecho
egy beépített shell, és nem szenved aexec
(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, hamv
sok fájl egyetlen könyvtárba, plmv * destdir
? Ha*
túl sok args " hibát ad a " számára, akkor ' ne tegyexargs
-et, hogy elsőként adja át az útvonalakat amv
-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ő.