Конец основного выражения должен быть отмечен <точкой с запятой> или знаком «плюс». Только знак «плюс», который следует сразу за аргументом, содержащим только два символа «{}», должен быть акцентирован на конце основного выражения. Другие варианты использования знака «плюс» не должны рассматриваться как особые. Если первичное выражение акцентировано <точка с запятой>, утилита utility_name должна вызываться один раз для каждого пути и первичное значение должно оцениваться как true, если утилита возвращает нулевое значение в качестве состояния выхода. Utility_name или аргумент , содержащий только два символа «{}» должен быть заменен на текущем пути. Если имя_устройства или аргументСтрока содержит два символа "{}", но не только два символа "{}", это определяется реализацией, заменяет ли find эти два символа или использует строку без изменений.
Если первичное выражение акцентировано знаком <плюс>, первичное всегда должно оцениваться как истинное, а имена путей, для которых оценивается первичное, должны быть объединены в наборы. Утилита utility_name
должна вызываться один раз для каждого набора агрегированных путей. Каждый вызов должен начинаться после агрегирования последнего пути в наборе и должен завершаться до выхода утилиты поиска и до агрегирования первого пути в следующем наборе (если есть) для этого первичного, но в противном случае не указано, является ли вызов происходит до, во время или после оценки других праймериз. Если любой вызов возвращает ненулевое значение в качестве состояния выхода, поиск
утилита должна возвращать ненулевой статус выхода. Аргумент, содержащий только два символа «{}», должен быть заменен набором агрегированных имен путей, причем каждое имя пути передается в качестве отдельного аргумента вызываемой утилите в том же порядке, в котором она была агрегирована. Размер любого набора из двух или более путей должен быть ограничен таким образом, чтобы выполнение утилиты не приводило к превышению системного лимита {ARG_MAX} . Если присутствует более одного аргумента, содержащего два символа «{}», поведение не определено.
find / -exec echo | wc
и измерив соотношение между количеством символов и количеством строк, и обнаружил, что максимальная длина используемой командной строкиfind
значительно меньше теоретического предела POSIX и намного ближе кSize of command buffer we are actually using
строке в выходных данныхxargs --show-limits
. Это верно для Linux и может быть верно для реализации Mac OSfind
, хотяxargs
не будет печатать значение в Mac OS. Есть идеи, почему это происходит?--show-limits
POSIX не указывает, реализация Mac OSxargs
не поддерживает его.find / -exec echo | wc
не сработает Помните, чтоARG_MAX
возвращаются байты. И это максимальная длина аргументов дляexec(3)
функций.--show-limits
это не POSIX, хотя это не максимальная длина аргумента, используемаяfind
, который использует меньшее значение. Я не понимаю, почему вы говорите, чтоfind / -exec echo | wc
это не сработает: по моему мнению, это хороший способ оценить реальную стоимость (и, как я вижу, лучше, чем использоватьgetconf ARG_MAX
). Кроме того, моя файловая система в основном, если не все символы ASCII, так что количество символов примерно равно количеству байтов.find / -exec sh -c 'echo $@ | wc -c' _ {} +
isntead.find / -exec echo {} + | wc -lc
Существует максимальная длина списка аргументов для нового процесса в системе POSIX.
find
разделит выполнение, если пути к файлам длиннее, чем этот. Чтобы увидеть ограничение для Linux, используйтеxargs --show-limits
(не работайте в Mac OS, если кто-то знает лучшую альтернативу, пожалуйста, прокомментируйте здесь)edit: украденный прямо из ответа Gnouc, POSIX способ получить максимальную длину списка аргументов
getconf ARG_MAX
. Тем не менее, я провел эксперимент на моей машине Mac OS, и, похоже,find
использует чуть больше половины этого числа. Это согласуется с тем фактом, что в системе, где он работает,xargs --show-limits
говорит нам, что он не будет использовать максимальную длину аргумента (в этом случае он также будет использовать около половины этого числа), однако я не смог найти объяснение для этого.редактировать 2: кажется, что единственный надежный способ определить, сколько параметров
find
будет слипаться для каждого вызова, это эксперимент, например, запустивТак как выходные данные
find
имеют строку для каждогоecho
вызова, их можно сосчитать, используяwc -l
. Общее число байтовecho
ed является выходомwc -c
вместо. Разделив один на другой, вы получите среднее число байтов в параметрах для каждого вызова команды (хотя и немного более низкое значение из-за округления, примерно половина средней длины пути в вашей системе)источник
xargs
не использует полную максимальную длину аргумента, потому что многие программы добавляют несколько дополнительных аргументов, а затем передают аргументы другим программам. Еслиxargs
аргументы заполняются до абсолютного максимума, такие программы ломаются, потому что не было бы места для этих дополнительных аргументов.xargs
илиfind
?yes . | xargs | head -n 1 | wc -c
), и сравнивая это с выводомgetconf ARG_MAX
. Но, на самом деле, пробуя это в моей системе, я получаю настолько большую разницу, что кажется, что есть нечто большее, чем я знаю.