„Lista argumentów za długa” po raz kolejny
Jakiś czas temu pisałem o komunikacie „Lista argumentów za długa„, którym może nas uraczyć system Uniksowy w przypadku zaserwowania wywoływanemu poleceniu zbyt długiej listy z argumentami (czyli komunikat jest nawet dość dokładny :-)). Ale dlaczego tak się właściwie dzieje i w którym momencie nasza lista robi się dla systemu „za długa”? Okazuje się, że wszystko to przez POSIX i jego opcję ARG_MAX. Standardowo w Linuksach (przynajmniej tych z kernelem w wersji 2.6, ale – żeby nie było zbyt prosto – niższej, niż 2.6.33) wartość tego parametru ustawiona jest na 128KB (czyli 131072 bajtów).
Możemy sprawdzić, jak to wygląda u nas:
[kbechler@flame ~]$ uname -r
2.6.18-308.1.1.el5
[kbechler@flame ~]$ getconf ARG_MAX
131072
[kbechler@flame ~]$
Czy można zmienić wartość ARG_MAX? Ponieważ w Linuksie da się zmienić wszystko, a ta opcja nie stanowi wyjątku, odpowiedź brzmi – TAK. Z drugiej strony – czy powinniśmy to robić? Według mnie NIE. Bo niby po co? Wszystkie przypadki, w których tytułowy komunikat jest przeszkodą, można „załatwić” iteracją po liście plików lub wykorzystać do pomocy xargs. Jeżeli jednak zmienimy ARG_MAX, to zmienią nam się „warunki środowiskowe” wszystkich uruchamianych programów, a w szczególności zwiększy się zapotrzebowanie systemu na RAM, co z kolei w zauważalny sposób wpłynie na jego szybkość. Poza tym jest to tylko przesuwanie limitów, a nie rozwiązywanie problemów, więc – jeżeli już teraz mamy taki problem – jest duża szansa, że w przyszłości znowu będziemy zmuszeni do zmian. Generalizując: w tym wypadku lepszym pomysłem wydaje mi się wyeliminowanie problemu (np. poprzez wykorzystanie iteracji) niż przesuwanie go w czasie (za pomocą zwiększania limitów).
Jeżeli jednak ktoś się upiera przy zmianie limitów, to w przypadku kerneli > 2.6.33 (gdzie wartość ARG_MAX jest równa 1/4 wartości „user-space stack”) jest to bardzo proste:
[kbechler@fedora ~]$ uname -r
3.4.2-1.fc16.i686.PAE
[kbechler@fedora ~]$ getconf ARG_MAX
2097152
[kbechler@fedora ~]$ ulimit -s
8192
[kbechler@fedora ~]$ ulimit -s 2048
[kbechler@fedora ~]$ ulimit -s
2048
[kbechler@fedora ~]$ getconf ARG_MAX
524288
Dla ciekawskich jeszcze LINK, gdzie można poczytać o zagadnieniu trochę dokładniej.