Po uruchomieniu polecenia, takiego jak ls */*/*/*/*.jpg
, pojawia się błąd
-bash: /bin/ls: Argument list too long
Wiem, dlaczego tak się dzieje: dzieje się tak, ponieważ istnieje ograniczenie jądra dotyczące ilości miejsca na argumenty polecenia. Standardową radą jest zmiana polecenia, którego używam, aby uniknąć wymagania tak dużej ilości miejsca na argumenty (np. Użyj find
i xargs
).
A jeśli nie chcę zmieniać polecenia? Co jeśli chcę nadal używać tego samego polecenia? Jak sprawić, by wszystko „po prostu działało” bez wyświetlania tego błędu? Jakie rozwiązania są dostępne?
Komentarze
- Przydatna lektura: Bash FAQ 95 . Bez zmiany polecenia tam ' niewiele możesz zrobić poza rekompilacją w celu zwiększenia maksymalnego rozmiaru listy argumentów lub zmianą struktury katalogów, aby było mniej plików.
- @ jw013 w oparciu o wersję jądra Linuksa może być możliwe zwiększenie listy argumentów – zobacz unix.stackexchange.com/a/45161/8979 , aby uzyskać szczegółowe informacje o zmianie ostatnie systemy.
- @UlrichDangel, tak, jest to możliwe! Zobacz moją odpowiedź; moja odpowiedź pokazuje, jak to zrobić (na L inux, z najnowszym jądrem).
Odpowiedź
W systemie Linux maksymalna ilość miejsca na polecenia argumenty to 1/4 dostępnego miejsca na stosie. Więc rozwiązaniem jest zwiększenie ilości miejsca dostępnego na stosie.
Krótka wersja: uruchom coś takiego jak
ulimit -s 65536
Dłuższa wersja : Domyślna ilość miejsca dostępnego dla stosu to około 8192 KB. Możesz zobaczyć ilość dostępnego miejsca w następujący sposób:
$ ulimit -s 8192
Wybierz większą liczbę i ustaw ilość dostępnego miejsca dla stosu. Na przykład, jeśli chcesz dopuścić do 65536 KB na stos, uruchom to:
$ ulimit -s 65536
Być może będziesz musiał się zastanowić, jak duże to potrzeba być, używając metody prób i błędów. W wielu przypadkach jest to szybkie i brudne rozwiązanie, które eliminuje konieczność modyfikowania polecenia i wypracowania składni find
, xargs
itd. (chociaż zdaję sobie sprawę, że ma to inne zalety).
Uważam, że jest to specyficzne dla Linuksa. Podejrzewam, że prawdopodobnie nie pomoże w żadnym innym systemie operacyjnym Unix (nie testowano).
Komentarze
- Możesz sprawdzić, czy zadziałało : $ getconf ARG_MAX 2097152 $ ulimit -s 65535 $ getconf ARG_MAX 16776960
- Czy to oznacza, że jeśli ustawię nieograniczony rozmiar stosu za pomocą
ulimit -s unlimited
, rozmiar wiersza poleceń będzie też bez ograniczeń?
Odpowiedz
Zamiast ls */*/*/*/*.jpg
, spróbuj:
echo */*/*/*/*.jpg | xargs ls
xargs
(1) wie, jaka jest maksymalna liczba argumentów w systemie i podzieli swoje standardowe wejście, aby wywołać określony wiersz poleceń wiele razy bez większej liczby argumentów niż ten limit, cokolwiek to jest (możesz również ustawić go poniżej maksymalnego poziomu systemu operacyjnego za pomocą -n
opcja).
Załóżmy na przykład, że limit to 3 argumenty i masz pięć plików. W takim przypadku xargs
wykona ls
dwukrotnie:
-
ls 1.jpg 2.jpg 3.jpg
-
ls 4.jpg 5.jpg
Często jest to idealne rozwiązanie, ale nie zawsze – na przykład nie można polegaj na ls
(1) sortowaniu wszystkich wpisów poprawnie, ponieważ każdy osobny ls
-invocation posortuje tylko podzbiór wpisów nadany mu przez xargs
.
Chociaż możesz zwiększyć limit zgodnie z sugestiami innych, nadal będzie istniał limit – i któregoś dnia Twoja kolekcja JPG znów ją przerośnie. Powinieneś przygotować swoje skrypty do obsługi nieskończonej liczby …
Komentarze
- Dziękujemy za pomysł! To nie jest złe obejście. Dwa ostrzeżenia: 1. To psuje katalogi i nazwy plików, które mają spacje w nazwie, więc ' nie jest idealnym zamiennikiem. 2. Czy będzie to ten sam problem z
Argument list too long
, ale dlaecho
zamiastls
, w powłokach, w którychecho
nie jest poleceniem wbudowanym powłoki? (Może to ' nie jest problemem w większości powłok, więc może to ' jest nieistotne.) - Tak , problemy ze znakami specjalnymi w nazwach plików. Najlepiej jest użyć
find
z predykatem-print0
– i przesłać jego dane wyjściowe doxargs
z opcją-0
.echo
to wbudowana powłoka, która nie podlega ograniczeniom wiersza poleceńexec
(3). - Działa to z poleceniami, które oczekują argumentu zmiennej jako ostatniego parametru, na przykład
ls
, ale co mam zrobić, gdy chcęmv
wiele plików do jednego katalogu, npmv * destdir
? Jeśli*
daje " za dużo argumentów " błąd, mogę ' t spraw, abyxargs
przekazały ścieżki jako pierwsze wmv
, czy mogę? / li> - Sprawdź stronę podręcznika pod kątem
xargs
w twoim systemie – na przykład we FreeBSD pomoże-J
ty z tym zadaniem. Jeśli w Twoim systemie operacyjnym nie ma sposobu, aby to zrobić, ' będziesz musiał napisać niestandardowy skrypt, aby zmienić kolejność argumentów. Na przykład:destdir=$1; shift; mv "$@" "$destdir"
. Następnie przekaż ten nowy skrypt doxargs
:.... | xargs newscript $destdir
Answer
Ten artykuł na temat Linux Journal zawiera 4 rozwiązania. Tylko czwarte rozwiązanie nie wymaga zmiany polecenia:
Metoda nr 4 polega na ręcznym zwiększeniu liczby stron przydzielonych w jądrze dla wiersza poleceń argumenty. Jeśli spojrzysz na plik include / linux / binfmts.h, u góry znajdziesz następujące informacje:
/* * 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
Aby zwiększyć ilość pamięci poświęcony argumentom wiersza poleceń, wystarczy podać wartość MAX_ARG_PAGES z większą liczbą. Gdy ta edycja zostanie zapisana, po prostu przekompiluj, zainstaluj i zrestartuj do nowego jądra tak, jak robisz to zwykle.
Na moim własnym systemie testowym udało mi się rozwiązać wszystkie moje problemy, podnosząc tę wartość do 64. Po rozległych testowania, nie miałem ani jednego problemu od momentu przełączenia. Jest to całkowicie oczekiwane, ponieważ nawet przy
MAX_ARG_PAGES
ustawionym na 64, najdłuższy możliwy wiersz poleceń, jaki mogłem wygenerować, zajmowałby tylko 256 KB pamięci systemowej – niewiele jak na dzisiejsze standardy sprzętowe systemu .Zalety metody nr 4 są oczywiste. Teraz możesz po prostu uruchomić polecenie w normalny sposób i zakończy się ono pomyślnie. Wady są równie jasne. Jeśli zwiększysz ilość dostępnej pamięci do wiersza poleceń poza ilość dostępnej pamięci systemowej, możesz stworzyć atak DOS na swój własny system i spowodować jego awarię. W szczególności w systemach z wieloma użytkownikami nawet niewielki wzrost może mieć znaczący wpływ, ponieważ każdemu użytkownikowi przydzielane jest wtedy dodatkową pamięć. Dlatego zawsze przeprowadzaj obszerne testy w swoim własnym środowisku, ponieważ jest to najbezpieczniejszy sposób określenia, czy metoda nr 4 jest dla Ciebie realną opcją.
Zgadzam się, że to ograniczenie jest bardzo irytujące.