Jeśli lista argumentów jest zbyt długa (pamiętaj, że * rozwija się do listy wszystkich plików, które pasują do globu), możesz obejść ją używając np . IFS="\n" for file in /src/*; do mv "$file" /dst/; doneLub rsync -a /src/ /dst/.
DopeGhoti
Odpowiedzi:
18
Zależy to w dużej mierze od systemu i wersji, liczby i wielkości argumentów oraz liczby i wielkości nazw zmiennych środowiskowych.
Tradycyjnie w Uniksie limit (jak donosi getconf ARG_MAX) był mniej więcej w stosunku do łącznego rozmiaru:
Długość ciągów argumentów (łącznie z zakończeniem '\0')
Długość tablicy wskaźników do tych ciągów, czyli zazwyczaj 8 bajtów na argument w systemie 64-bitowym
Długość ciągów środowiska (łącznie z zakończeniem '\0'), przy czym ciąg znaków środowiska jest umownie podobny var=value.
Długość tablicy wskaźników do tych ciągów, czyli zazwyczaj 8 bajtów na argument w systemie 64-bitowym
Pamiętając, że cprównież liczy się jako argument (jest to pierwszy argument).
W systemie Linux zależy to od wersji. Zachowanie tam się ostatnio zmieniło, gdy nie jest to już stała przestrzeń.
Sprawdzanie w systemie Linux 3.11 getconf ARG_MAXpokazuje teraz jedną czwartą limitu ustawionego na stosie lub 128 kB, jeśli jest to mniej niż 512 kB.
Limit ten dotyczy skumulowanego rozmiaru argumentów i ciągów środowiska oraz pewnych kosztów ogólnych (podejrzewam, że ze względu na wyrównanie na granicach strony). Rozmiar wskaźników nie jest brany pod uwagę.
Szukając limitu, otrzymuję:
$ /bin/true {1..164686}
$ /bin/true {1..164687}
zsh: argument list too long: /bin/true
$ x= /bin/true {1..164686}
$ x=1 /bin/true {1..164686}
zsh: argument list too long: /bin/true
Maksymalny łączny rozmiar przed zerwaniem w tym przypadku wynosi:
To nie znaczy, że możesz przekazać milion pustych argumentów. W systemie 64-bitowym 1 milion pustych argumentów tworzy listę wskaźników o wielkości 8 MB, która byłaby powyżej mojego rozmiaru stosu wynoszącego 4 MB.
(zauważysz, że nie jest to błąd E2BIG. Nie jestem pewien, w którym momencie proces zostaje tam zabity, jeśli jest w ramach execvewywołania systemowego lub później).
Zwróć także uwagę (nadal w Linuksie 3.11), że maksymalny rozmiar pojedynczego argumentu lub łańcucha środowiska wynosi 128kiB, niezależnie od wielkości stosu.
$ /bin/true ${(l.131071..a.)${:-}} # 131072 OK
$ /bin/true ${(l.131072..a.)${:-}} # 131073 not
zsh: argument list too long: /bin/true
$ /bin/true ${(l.131071..a.)${:-}} ${(l.131071..a.)${:-}} # 2x 131072 OK
Czy możesz się podzielić, jak wymyśliłeś 164686numer? tj. jak obliczyłeś, że sekwencja będzie 2097152mniejsza niż rozmiar ARG_MAX?
Sergiy Kolodyazhnyy
14
Będzie to zależeć od wartości ARG_MAX, która może zmieniać się między systemami. Aby znaleźć wartość dla uruchomienia systemu (pokazując wynik na moim jako przykład):
$ getconf ARG_MAX
2097152
Nie ma to nic wspólnego z cptwoją powłoką, jest to limit narzucony przez jądro, nie będzie wykonywał exec()poleceń ( ), jeśli ich argumenty są dłuższe niż ARG_MAX. Jeśli więc podana przez ciebie długość listy argumentów cpjest większa niż ARG_MAX, cppolecenie w ogóle się nie uruchomi.
Aby odpowiedzieć na główne pytanie, nie cpbędzie przetwarzał żadnych plików, ponieważ nigdy nie zostanie wykonany z tyloma argumentami. Powinienem również wspomnieć, że nie zależy to od liczby argumentów, ale od ich długości. Możliwe, że masz ten sam problem z bardzo nielicznymi, ale bardzo długimi nazwami plików.
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
Lubrsync -a /src/ /dst/
.Odpowiedzi:
Zależy to w dużej mierze od systemu i wersji, liczby i wielkości argumentów oraz liczby i wielkości nazw zmiennych środowiskowych.
Tradycyjnie w Uniksie limit (jak donosi
getconf ARG_MAX
) był mniej więcej w stosunku do łącznego rozmiaru:'\0'
)'\0'
), przy czym ciąg znaków środowiska jest umownie podobnyvar=value
.Pamiętając, że
cp
również liczy się jako argument (jest to pierwszy argument).W systemie Linux zależy to od wersji. Zachowanie tam się ostatnio zmieniło, gdy nie jest to już stała przestrzeń.
Sprawdzanie w systemie Linux 3.11
getconf ARG_MAX
pokazuje teraz jedną czwartą limitu ustawionego na stosie lub 128 kB, jeśli jest to mniej niż 512 kB.(
zsh
składnia poniżej):Limit ten dotyczy skumulowanego rozmiaru argumentów i ciągów środowiska oraz pewnych kosztów ogólnych (podejrzewam, że ze względu na wyrównanie na granicach strony). Rozmiar wskaźników nie jest brany pod uwagę.
Szukając limitu, otrzymuję:
Maksymalny łączny rozmiar przed zerwaniem w tym przypadku wynosi:
To nie znaczy, że możesz przekazać milion pustych argumentów. W systemie 64-bitowym 1 milion pustych argumentów tworzy listę wskaźników o wielkości 8 MB, która byłaby powyżej mojego rozmiaru stosu wynoszącego 4 MB.
(zauważysz, że nie jest to błąd E2BIG. Nie jestem pewien, w którym momencie proces zostaje tam zabity, jeśli jest w ramach
execve
wywołania systemowego lub później).Zwróć także uwagę (nadal w Linuksie 3.11), że maksymalny rozmiar pojedynczego argumentu lub łańcucha środowiska wynosi 128kiB, niezależnie od wielkości stosu.
źródło
164686
numer? tj. jak obliczyłeś, że sekwencja będzie2097152
mniejsza niż rozmiar ARG_MAX?Będzie to zależeć od wartości ARG_MAX, która może zmieniać się między systemami. Aby znaleźć wartość dla uruchomienia systemu (pokazując wynik na moim jako przykład):
Nie ma to nic wspólnego z
cp
twoją powłoką, jest to limit narzucony przez jądro, nie będzie wykonywałexec()
poleceń ( ), jeśli ich argumenty są dłuższe niżARG_MAX
. Jeśli więc podana przez ciebie długość listy argumentówcp
jest większa niż ARG_MAX,cp
polecenie w ogóle się nie uruchomi.Aby odpowiedzieć na główne pytanie, nie
cp
będzie przetwarzał żadnych plików, ponieważ nigdy nie zostanie wykonany z tyloma argumentami. Powinienem również wspomnieć, że nie zależy to od liczby argumentów, ale od ich długości. Możliwe, że masz ten sam problem z bardzo nielicznymi, ale bardzo długimi nazwami plików.Aby obejść te błędy, uruchom polecenie w pętli:
źródło
C
mogą mieć problemy z ARG_MAX i naprawdę długie nazwy plików?