Podczas próby otwarcia ls *.txt | wc -l
katalogu zawierającego wiele plików pojawia się następujący błąd :
-bash: /bin/ls: Argument list too long
Czy próg tej „listy argumentów” zależy od dystrybucji lub specyfikacji komputera? Zwykle przesyłam wynik tak dużego wyniku do niektórych innych poleceń ( wc -l
na przykład), więc nie interesują mnie ograniczenia terminala.
ls
wyjście „s , co jest złym pomysłem, więc lepiej unikać. Aby zliczyć, zobacz Jaki jest najlepszy sposób na policzenie liczby plików w katalogu? , w przypadku trudnego obejścia sprawdź, dlaczego dla pętli nie występuje błąd „zbyt długi argument”? .Odpowiedzi:
Twój komunikat o błędzie lista argumentów zbyt długo pochodzi z * o
ls *.txt
.Ograniczenia te stanowią bezpieczeństwo zarówno dla programów binarnych, jak i dla jądra. Na tej stronie zobaczysz więcej informacji o tym, a także o tym, jak jest wykorzystywany i obliczany.
Nie ma takiego ograniczenia rozmiaru rury. Możesz więc po prostu wydać to polecenie:
Uwaga: we współczesnym systemie Linux dziwne znaki w nazwach plików (np. Nowe wiersze) będą oznaczone znakami ucieczki za pomocą narzędzi takich jak
ls
lubfind
, ale nadal wyświetlane z * . Jeśli korzystasz ze starego Uniksa, będziesz potrzebować tego poleceniaNB2: Zastanawiałem się, jak stworzyć plik z nową linią w nazwie. To nie jest takie trudne, kiedy znasz już sztuczkę:
źródło
-maxdepth 1
jeśli nie zamierzasz liczyć plików w podkatalogach.-exec echo \;
.find
. Wfind
systemie OS X i systemach opartych na busyboksie, i jak sądzę, każdy system oparty na BSD pokazuje nazwę pliku z nową linią, co może zepsuć się z liczbą.wc -l
liczy nowe linie. Więc chce go mieć nowe linie.Zależy to głównie od twojej wersji jądra Linux.
Powinieneś być w stanie zobaczyć limit swojego systemu, uruchamiając
która określa maksymalną liczbę bajtów, jaką wiersz poleceń może mieć po rozwinięciu przez powłokę.
W Linuksie <2.6.23 limit wynosi zwykle 128 KB.
W Linuksie> = 2.6.25 limit wynosi 128 KB lub 1/4 wielkości stosu (patrz
ulimit -s
), w zależności od tego, która wartość jest większa.Zobacz stronę manuala execve (2), aby poznać wszystkie szczegóły.
Niestety, potokowanie
ls *.txt
nie rozwiąże problemu, ponieważ limit jest w systemie operacyjnym, a nie w powłoce.Powłoka rozszerza
*.txt
, a następnie próbuje zadzwonići masz tyle pasujących plików
*.txt
, że przekraczasz limit 128 KB.Będziesz musiał zrobić coś takiego
zamiast.
(I zobacz poniższe komentarze Shawna J. Goffa na temat nazw plików zawierających nowe linie).
źródło
.
i co-maxdepth 1
oznacza w ostatnim wierszu? Dzięki! : D.
oznacza bieżący katalog, co-maxdepth 1
oznacza, że nie przegląda on podkatalogów. To miało pasować do tych samych plików, co*.txt
.Kolejne obejście:
Mimo że
ls
produkuje więcej danych wyjściowych niżls *.txt
produkuje (lub próbuje produkować), nie napotyka problemu „zbyt długich argumentów”, ponieważ nie przekazujesz żadnych argumentówls
. Zauważ, żegrep
bierze wyrażenie regularne zamiast wzorca pasującego do pliku.Możesz użyć:
(zakładając, że Twoja wersja
ls
obsługuje tę opcję). Mówils
to, aby nie sortować danych wyjściowych, co może zaoszczędzić zarówno czas, jak i pamięć - w tym przypadku kolejność nie ma znaczenia, ponieważ tylko zliczasz pliki. Zasoby wydane na sortowanie danych wyjściowych zwykle nie są znaczące, ale w tym przypadku wiemy już, że masz bardzo dużą liczbę*.txt
plików.I powinieneś rozważyć reorganizację swoich plików, aby nie było ich tak wiele w jednym katalogu. To może, ale nie musi być wykonalne.
źródło
MAX_ARG_PAGES wydaje się być parametrem jądra. Używanie
find
ixargs
jest typową kombinacją do ograniczenia tego limitu, ale nie jestem pewien, czy to zadziaławc
.Pipingowanie wyjścia
find . -name \*\.txt
do pliku i zliczanie linii w tym pliku powinno służyć jako obejście.źródło
ls
wyjściem, to nie rozwiąże. Dopóki znak wieloznaczny * .txt zostanie rozwinięty powyżej limitu, nie powiedzie się nawet przed uruchomieniemls
i wygenerowaniem jakiegokolwiek wyniku.ls
, należy określić,-maxdepth 1
aby unikać rekurencyjnego skanowania podkatalogów.To może być brudne, ale działa na moje potrzeby i w ramach moich kompetencji. Nie sądzę, że działa bardzo szybko, ale pozwoliło mi to kontynuować.
Otrzymywałem listę 90 000 plików JPG i przesyłałem je do avconv, aby wygenerować upływ czasu.
Wcześniej używałem ls * .jpg | avconv, zanim natknąłem się na ten problem.
źródło