(3 odpovědi)
Uzavřeno před 2 lety.
Kontext pro otázku:Podle specifikací POSIX je ARG_MAX maximální délka argumentů příkazového řádku na exec()
rodina funkcí. Což mě vede k přesvědčení, že jde o skutečné číslo argumentů, které však zjevně nefungovaly:
$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$
Je zřejmé, že to funguje dobře, přestože má délku přes 8192 položek. Podle D.W. odpovědi 8192
je údajně velikost v kB. Je tedy zřejmé, že předchozí předpoklad byl chybný.
Zde přichází skutečná otázka:Jak zjistím množství položek, které skutečně bude dostat se nad limit 8192 kB? Jinými slovy, jaký druh výpočtu musím provést, abych zajistil, že *.jpg
typ glob bude mít za následek Argument list too long
chyba?
Upozorňujeme, že toto není duplikát Co definuje maximální velikost argumentu jednoho příkazu. Vím o getconf ARG_MAX
a ulimit -s
hodnoty, to není moje otázka. Potřebuji vědět, jak vygenerovat dostatek argumentů ve velikosti, která bude nad limit . Jinými slovy, musím najít způsob, jak chybu získat, ne se jí vyhnout.
Přijatá odpověď:
Pomocí getconf ARG_MAX
vygenerovat dlouhý seznam x
a volání externího nástroje s tímto argumentem by vygenerovalo chybu „Seznam argumentů je příliš dlouhý“:
$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long
Prostředí a délka řetězce /bin/echo
bude zahrnuto v tom, co způsobuje chybu, takže se můžeme pokusit najít největší možné číslo odečtením těchto:
$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin
(Tento shell jsem spustil pomocí env -i sh
, takže existuje pouze PATH
proměnná v prostředí)
$ /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long
Pořád moc dlouho. O kolik?
i=0
while ! /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
i=$(( i + 1 ))
done
Tato smyčka se ukončí pro i=8
.
Takže existují čtyři bajty, které nemohu okamžitě započítat (čtyři z osmi musí být pro název z PATH
proměnná prostředí). Toto jsou nulové terminátory pro čtyři řetězce PATH
, hodnota PATH
, /bin/echo
a dlouhý řetězec x
znaky.
Všimněte si, že každý argument je ukončený hodnotou null, takže čím více argumentů příkazu máte, tím kratší může být jejich kombinovaná délka.
Také jen pro ukázku efektu velkého prostředí:
$ export BIG=$( perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )
$ /bin/echo hello
sh: /bin/echo: Argument list too long
$ /bin/echo
sh: /bin/echo: Argument list too long