GNU/Linux >> Znalost Linux >  >> Linux

Jak způsobit chybu „Příliš dlouhý seznam argumentů“?

Tato otázka zde již obsahuje odpovědi :Co definuje maximální velikost pro jeden argument příkazu?

(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.

Související:Linux – Proč detekce USB klíče trvá tak dlouho?

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

Linux
  1. /usr/bin Vs /usr/local/bin Na Linuxu?

  2. Jak provést Chmod bez /usr/bin/chmod?

  3. Není důvod mít Shebang ukazující na /bin/sh spíše než /bin/bash?

  1. Linux – sloučení /usr/bin A /usr/sbin do /bin (gnu/linux)?

  2. Nainstalujte binární soubory do /bin, /sbin, /usr/bin a /usr/sbin, interakce s --prefix a DESTDIR

  3. bash:/bin/tar:Při komprimaci mnoha souborů pomocí tar je seznam argumentů příliš dlouhý

  1. Jak obrátit seznam slov v řetězci shellu?

  2. Kdy mám použít /dev/shm/ a kdy /tmp/?

  3. Jak zjistit, ze které složky běží proces?