Kun suoritan komennon, kuten ls */*/*/*/*.jpg
, saan virheen
-bash: /bin/ls: Argument list too long
Tiedän miksi näin tapahtuu: se johtuu siitä, että komennon argumenteille on varattu ytimen raja. Tavallinen ohje on vaihtaa käyttämäni komento, jotta vältetään niin paljon tilaa argumenteille (esim. find
ja xargs
).
Entä jos en halua muuttaa komentoa? Entä jos haluan jatkaa saman komennon käyttöä? Kuinka voin saada asiat ”toimimaan” ilman virheitä? Mitkä ratkaisut ovat käytettävissä?
kommentit
- Hyödyllistä tietoa: Bashin usein kysytyt kysymykset 95 . Muuttamatta komentoa siellä ' ei ole paljon muuta, mitä voit tehdä uudelleen kääntämisen lisäksi argumenttiluettelon enimmäiskoon lisäämiseksi tai hakemistorakenteen muuttamiseksi siten, että tiedostoja on vähemmän.
- @ jw013 linux-ytimen version perusteella voi olla mahdollista lisätä argumenttiluetteloa – katso lisätietoja muutoksesta unix.stackexchange.com/a/45161/8979 uusimmat järjestelmät.
- @UlrichDangel, Yup, se on mahdollista! Katso vastaukseni; vastaukseni näyttää, miten se tehdään (L inux, riittävän äskettäisellä ytimellä).
vastaus
Linuxissa komentojen enimmäistila argumentit ovat 1/4 käytettävissä olevan pinotilan määrästä. Joten ratkaisu on lisätä pinon käytettävissä olevan tilan määrää.
Lyhyt versio: suorita jotain
ulimit -s 65536
Pidempi versio : Pinoa varten käytettävissä oleva oletusarvo on noin 8192 kt. Näet käytettävissä olevan tilan määrän seuraavasti:
$ ulimit -s 8192
Valitse suurempi numero ja aseta pinolle käytettävissä oleva tila. Jos esimerkiksi haluat yrittää sallia pinolle jopa 65536 kt, suorita tämä:
$ ulimit -s 65536
Saatat joutua pelaamaan, kuinka suurta tätä tarvitaan olla käyttämällä kokeiluvirheitä. Monissa tapauksissa tämä on nopea ja likainen ratkaisu, joka poistaa tarpeen muuttaa komentoa ja selvittää find
, xargs
jne. (vaikka ymmärrän, että sillä on muita etuja).
Uskon, että tämä on Linux-kohtainen. Epäilen, että se todennäköisesti ei auta missään muussa Unix-käyttöjärjestelmässä (ei testattu).
Kommentit
- Voit varmistaa näin, että se toimi : $ getconf ARG_MAX 2097152 $ ulimit -s 65535 $ getconf ARG_MAX 16776960
- Tarkoittaako tämä sitä, että jos teen pinokoon rajoittamattomaksi
ulimit -s unlimited
-toiminnolla, komentorivin koko on rajoittamaton?
Vastaa
ls */*/*/*/*.jpg
sijaan kokeile:
echo */*/*/*/*.jpg | xargs ls
xargs
(1) tietää, mikä on järjestelmän enimmäismäärä argumentteja, ja hajottaa vakiotulonsa kutsumaan määritettyä komentoriviä useita kertoja ilman enempää argumentteja kuin tämä raja, riippumatta siitä, mikä se on (voit myös asettaa sen alhaisemmaksi kuin käyttöjärjestelmän ”suurin” -n
vaihtoehto).
Oletetaan esimerkiksi, että raja on 3 argumenttia ja sinulla on viisi tiedostoa. Tällöin xargs
suorittaa ls
kahdesti:
-
ls 1.jpg 2.jpg 3.jpg
-
ls 4.jpg 5.jpg
Usein tämä sopii täydellisesti, mutta ei aina – esimerkiksi et voi luottaa siihen, että ls
(1) lajittelee kaikki merkinnät sinulle oikein, koska kukin erillinen ls
-kutsu lajittelee vain sille xargs
antamien merkintöjen osajoukon.
Vaikka voit kaataa rajan muiden suosittelemalla tavalla, raja on silti olemassa – ja jonain päivänä JPG-kokoelmasi kasvaa uudestaan. Sinun tulisi valmistautua käsikirjoituksesi käsittelemään ääretön määrä …
Kommentit
- Kiitos ideasta! Tämä ei ole huono kiertotapa. Kaksi varoitusta: 1. Tämä rikkoo hakemistot ja tiedostonimet, joiden nimessä on välilyöntejä, joten se ' ei ole täydellinen korvike. 2. Onko kyse samasta ongelmasta
Argument list too long
kanssa, muttaecho
-kohdassals
, kuoreissa, joissaecho
ei ole kuoren sisäänrakennettu komento? (Ehkä se ' ei ole ongelma useimmissa kuoreissa, joten ehkä ' ei ole merkitystä.) - Kyllä , tiedostonimien erikoismerkit ovat ongelma. Parasta panostasi on käyttää
find
predikaatin-print0
kanssa – ja liittää sen lähtöxargs
vaihtoehdolla-0
.echo
on sisäänrakennettu kuori eikä kärsi komentorivirajoituksestaexec
(3). - Tämä toimii komentojen kanssa, jotka odottavat muuttujan argumenttia viimeisenä parametrina, kuten
ls
, mutta mitä teen, kun haluanmv
monta tiedostoa yhteen hakemistoon, esimmv * destdir
? Jos*
antaa " liian monta argumenttia " -virheen, voin ' ei saaxargs
siirtää polut ensimmäisinä kohtaanmv
jollain tavalla, vai voinko? - Tarkista järjestelmän sivulta
xargs
– esimerkiksi FreeBSD: llä-J
auttaa sinulle tämän tehtävän kanssa. Jos käyttöjärjestelmässäsi ei ole mitään keinoa tehdä tämä, ' sinun on kirjoitettava oma komentosarja järjestämään argumentit uudelleen. Jotain tällaista:destdir=$1; shift; mv "$@" "$destdir"
. Anna sitten tämä uusi komentosarjaxargs
:.... | xargs newscript $destdir
Vastaa
Tässä Linux Journal -artikkelissa on neljä ratkaisua. Vain neljäs ratkaisu ei sisällä komennon muuttamista:
Menetelmässä 4 lisätään manuaalisesti ytimessä allokoitujen sivujen määrää komentoriville perustelut. Jos tarkastelet include / linux / binfmts.h-tiedostoa, löydät sen yläreunasta seuraavat:
/* * 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
Muistin määrän lisäämiseksi omistettu komentoriviargumenteille, sinun tarvitsee vain antaa MAX_ARG_PAGES -arvo suuremmalla luvulla. Kun tämä muokkaus on tallennettu, käännä uudelleen, asenna ja käynnistä se uudelle ytimelle tavalliseen tapaan.
Omassa testausjärjestelmässäni onnistuin ratkaisemaan kaikki ongelmani nostamalla tämän arvon 64: een. testauksessa, en ole kokenut yhtään ongelmaa vaihdon jälkeen. Tämä on täysin odotettua, koska vaikka
MAX_ARG_PAGES
olisi asetettu arvoon 64, pisin mahdollinen komentorivi, jonka voisin tuottaa, vie vain 256 kt järjestelmän muistia – ei kovin paljon nykypäivän järjestelmän laitteistostandardien mukaan .Menetelmän 4 edut ovat selvät. Pystyt nyt suorittamaan komennon tavalliseen tapaan, ja se suoritetaan onnistuneesti. Haitat ovat yhtä selvät. Jos korotat käytettävissä olevan muistin määrää komentoriville vapaan järjestelmämuistin määrän ulkopuolella, voit luoda DOS-hyökkäyksen omalle järjestelmällesi ja aiheuttaa sen kaatumisen. Erityisesti monen käyttäjän järjestelmissä jopa pienellä lisäyksellä voi olla merkittävä vaikutus, koska jokaiselle käyttäjälle osoitetaan sitten lisää muistia. Siksi testaa aina perusteellisesti omassa ympäristössäsi, koska tämä on turvallisin tapa selvittää, onko menetelmä # 4 sinulle käyttökelpoinen vaihtoehto.
Olen samaa mieltä siitä, että rajoitus on vakavasti ärsyttävä.