Odkryłem, że spowodowałoby to błąd „zbyt długi argument”:
ls *.*
I to by go nie podniosło:
for file in *.*
do
echo $file
done
Dlaczego?
Odkryłem, że spowodowałoby to błąd „zbyt długi argument”:
ls *.*
I to by go nie podniosło:
for file in *.*
do
echo $file
done
Dlaczego?
Odpowiedzi:
Błąd „zbyt długi argument” jest E2BIGwywoływany przez execvewywołanie systemowe, jeśli całkowity rozmiar argumentów (plus środowisko, w niektórych systemach) jest zbyt duży. execveWezwanie jest ten, który rozpoczyna procesów zewnętrznych, a konkretnie ładuje inny plik wykonywalny (jest inna rozmowa, forkna prowadzenie oddzielnego procesu, którego kod jest nadal z tego samego pliku wykonywalnego). forPętli wewnętrzna konstrukcja płaszcza tak, że nie obejmuje wywołanie execve. Polecenie ls *.*podnosi błąd nie po rozwinięciu globu, ale po lswywołaniu.
execvekończy się błędem, E2BIGgdy całkowity rozmiar argumentów polecenia jest większy niż ARG_MAX limit . Możesz zobaczyć wartość tego limitu w swoim systemie za pomocą polecenia getconf ARG_MAX. (Możliwe, że możesz przekroczyć ten limit, jeśli masz wystarczającą ilość pamięci; utrzymywanie poniżej ARG_MAXgwarancji, które execvebędą działać, dopóki nie wystąpi niepowiązany błąd).
execveLimit jest egzekwowany przez jądro, nakłada ograniczenia, ponieważ argumenty muszą zostać skopiowane przez pamięć jądra w jednym punkcie, a procesy użytkownika nie mogą żądać dowolnej ilości pamięci powłoki. Wewnątrz powłoki nie ma powodu, aby mieć limit, wszystko, co mieści się w pamięci wirtualnej, jest w porządku.
Przypuszczam, że w pierwszym przykładzie lsjest wykonywana bashprzez wywołanie systemowe fork/ execpair, w drugim cała praca jest wewnętrzna bash.
execWezwanie ma swoje granice, wewnętrzny roboczy bashzamiast nie ma (albo lepiej, ma różne ograniczenia, które nie mają nic wspólnego z exec, być może ilość dostępnej pamięci).
execw /usr/include/linux/limits.hzazwyczaj zdefiniowany jako ARG_MAX.
Ponieważ w tym przypadku lsjest to argument, a liczba argumentów jest ograniczona.
W przypadku forcyklu jest to tylko lista pozycji. Nie ma żadnych ograniczeń (o ile mi wiadomo).
for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
/bin/bashvs./bin/sh(który może być linkiem do myślnika)?