Czy istnieje jakiś limit znaków narzucony w bashu (lub innych powłokach) na jak długo może trwać wejście? Jeśli tak, jaki jest ten limit znaków?
To znaczy czy można napisać polecenie w bash, które jest zbyt długie, aby wiersz poleceń mógł zostać wykonany? Jeśli nie ma wymaganego limitu, czy istnieje sugerowany limit?
bash
shell
unix
command-line-arguments
Derek Halden
źródło
źródło
Odpowiedzi:
Limit długości wiersza poleceń nie jest narzucony przez powłokę, ale przez system operacyjny. Limit ten zwykle mieści się w zakresie stu kilobajtów. POSIX oznacza to ograniczenie,
ARG_MAX
a w systemach zgodnych z POSIX można o nie zapytać$ getconf ARG_MAX # Get argument limit in bytes
Np. Na Cygwin jest to 32000, a na różnych BSD i systemach Linux, których używam, wynosi od 131072 do 2621440.
Jeśli potrzebujesz przetworzyć listę plików przekraczającą ten limit, możesz przyjrzeć się
xargs
narzędziu, które wielokrotnie wywołuje program z podzbiorem argumentów nieprzekraczającymARG_MAX
.Odpowiadając na twoje konkretne pytanie, tak, można spróbować uruchomić polecenie ze zbyt długą listą argumentów. Powłoka wyświetli komunikat o błędzie „lista argumentów jest zbyt długa”.
Zauważ, że dane wejściowe do programu (czytane na stdin lub jakimkolwiek innym deskryptorze pliku) nie są ograniczone (tylko przez dostępne zasoby programu). Więc jeśli twój skrypt powłoki wczytuje łańcuch do zmiennej, nie jesteś ograniczony przez
ARG_MAX
. To ograniczenie nie dotyczy również poleceń wbudowanych powłoki.źródło
cmd <<< "$LONG_VAR"
otrzymam konstrukcję, a wartość LONG_VAR przekroczy limit, czy zepsułoby to moje polecenie?LONG_VAR
jest przekazywana na stdin - i to w całości odbywa się w shellu; nie jestcmd
interpretowany jako argument do , więc limit ARG_MAX dla fork () / exec () nie wchodzi w grę. Łatwo jest spróbować samemu: utwórz zmienną o zawartości przekraczającej ARG_MAX i uruchom polecenie.blah="$(cat /home/schwager/Music/Recordings/20090420\ 131623.m4a)"; cat <<< $blah >/dev/null
. Uwaga bez błędu.xargs
na MacOS 10.12.6 limitów ile próbuje umieścić w jednymexec()
zARG_MAX - 4096
. Tak więc używanie skryptówxargs
może działać, aż pewnego dnia ktoś umieści za dużo rzeczy w środowisku. Wchodzę w to teraz (obejdź to:)xargs -s ???
.Ok, mieszkańcy. Tak więc od dłuższego czasu akceptuję ograniczenia długości wiersza poleceń jako gospel. Co więc zrobić ze swoimi założeniami? Oczywiście - sprawdź je.
Mam do dyspozycji maszynę Fedora 22 (czyli: Linux z bash4). Utworzyłem katalog zawierający 500 000 i-węzłów (plików), każdy o długości 18 znaków. Długość wiersza poleceń wynosi 9500000 znaków. Utworzono w ten sposób:
seq 1 500000 | while read digit; do touch $(printf "abigfilename%06d\n" $digit); done
I zauważamy:
Pamiętaj jednak, że mogę to zrobić:
$ echo * > /dev/null
Ale to się nie udaje:
$ /bin/echo * > /dev/null bash: /bin/echo: Argument list too long
Mogę uruchomić pętlę for:
$ for f in *; do :; done
czyli kolejna wbudowana powłoka.
Uważne czytanie dokumentacji
ARG_MAX
stanów. Maksymalna długość argumentów funkcji exec . To znaczy: bez dzwonieniaexec
nie maARG_MAX
ograniczeń. To wyjaśniałoby, dlaczego polecenia wbudowane powłoki nie są ograniczone przezARG_MAX
.I rzeczywiście, mogę
ls
mój katalog, jeśli moja lista argumentów ma 109948 plików lub około 2089000 znaków (daj lub weź). Jednak gdy dodam jeszcze jeden 18-znakowy plik nazwy pliku, pojawia się zbyt długi błąd listy argumentów . Tak więcARG_MAX
działa zgodnie z zapowiedzią: wykonanie kończy się niepowodzeniem z więcej niżARG_MAX
znakami na liście argumentów - w tym, należy zauważyć, danymi środowiska.źródło
for f in *; do echo $f; done
ogóle nie rozwidla (wszystkie wbudowane). Więc nie wiem, czy combo find-xargs będzie szybsze; nie został przetestowany. Rzeczywiście, nie wiem, jaki jest zestaw problemów PO. Może mu sięfind /path/to/directory
to nie przyda, ponieważ zwróci ścieżkę do pliku. Może lubi prostotęfor f in *
pętli. Niezależnie od tego, rozmowa dotyczy ograniczenia wejścia liniowego, a nie wydajności. Pozostańmy więc przy temacie, który dotyczy długości wiersza poleceń.Istnieje ograniczenie bufora około 1024. Odczyt po prostu zawiesi się w trakcie wklejania lub wprowadzania. Aby rozwiązać ten problem, użyj opcji -e.
http://linuxcommand.org/lc3_man_pages/readh.html
-e użyj Readline, aby uzyskać wiersz w powłoce interaktywnej
Zmień odczyt na -e i irytujące zawieszanie się linii znika.
źródło
read
: „Czy jest możliwe napisanie w bashu polecenia, które jest zbyt długie, aby wiersz poleceń mógł zostać wykonany?”bash --noediting
, A po nowymecho somereallylongword
znaku zachęty spróbuj uruchomić polecenie , w którym niektóre wszystkie słowa są dłuższe niż 4090 znaków. Wypróbowane na Ubuntu 18.04, słowo zostało obcięte, więc oczywiście ma to coś wspólnego z wyłączeniem Readline.