Я виявив, що це призведе до помилки "занадто довгий аргумент":
ls *.*
І це не підніме це:
for file in *.*
do
echo $file
done
Чому?
Я виявив, що це призведе до помилки "занадто довгий аргумент":
ls *.*
І це не підніме це:
for file in *.*
do
echo $file
done
Чому?
Відповіді:
«Аргумент занадто довго» помилка E2BIG, піднятий execveсистемного виклику , якщо загальний розмір аргументів (плюс середовища, на деяких системах) занадто великий. execveВиклик є той , який запускає зовнішні процеси, в Зокрема , завантаження іншої виконуваний файл (є вхідний дзвінок, forkдля запуску окремого процесу, код якого до цих пір з того ж самого виконуваного файлу). forЦикл є внутрішньою конструкцією оболонки, тому він не пов'язаний з викликом execve. Команда ls *.*викликає помилку не тоді, коли глобус розгорнутий, а коли lsвикликається.
execveне вдається з помилкою, E2BIGколи загальний розмір аргументів команди перевищує ARG_MAX обмеження . За допомогою команди можна побачити значення цього обмеження у вашій системі getconf ARG_MAX. (Можливо, ви можете перейти цей ліміт, якщо у вас є достатня кількість пам'яті; зберігаючи ARG_MAXгарантії, які execveпрацюватимуть до тих пір, поки не виникне непов'язана помилка.)
execveОбмеження застосовується ядром, воно встановлює обмеження, оскільки аргументи потрібно копіювати через пам'ять ядра в один момент, і користувацькі процеси не можуть дозволити запитувати довільну кількість пам'яті оболонки. Всередині оболонки немає жодних причин мати обмеження, все, що вписується у віртуальну пам'ять, добре.
Я припускаю, що в першому прикладі lsвиконується bashчерез системний виклик fork/ execпара, у другому - все, що працює, є внутрішнім bash.
execВиклик має межі, внутрішня обробка bashзамість не має (або краще, має різні обмеження , які не мають нічого спільного з exec, можливо , обсягом доступної пам'яті).
execв, /usr/include/linux/limits.hяк правило, визначеному як ARG_MAX.
Тому що у разі lsце аргумент, а кількість аргументів обмежена.
У випадку forциклу це лише перелік елементів. Для цього немає обмежень (наскільки мені відомо).
for i in {00000001..20000000} ;do ((10#$i==1)) && break; done
/bin/bashпроти/bin/sh(що, можливо, посилання на тире)?