«Список аргументов слишком длинный»: как мне с этим справиться, не меняя мою команду?
Когда я запускаю команду как ls */*/*/*/*.jpg
, я получаю ошибку
-bash: /bin/ls: Argument list too long
Я знаю, почему это происходит: это потому, что существует ограничение ядра на количество пространства для аргументов команды. Стандартным советом является изменение команды, которую я использую, чтобы не требовать столько места для аргументов (например, использовать find
и xargs
).
- 'find -mtime -1 -print | xargs tar 'архивирует все файлы из каталога, игнорируя аргумент -mtime -1
- Перемещение файлов с помощью find + xargs: target не является каталогом?
- / usr / bin / awk: слишком длинный список аргументов
- Есть ли способ манипулировать порядком аргументов stdin при использовании xargs, так же, как awk как $ 0, $ 1, $ 2 и т. Д.?
- cp после того, как xargs не работает
Что делать, если я не хочу менять команду? Что делать, если я хочу продолжать использовать ту же команду? Как я могу заставить вещи «просто работать», не получив эту ошибку? Какие существуют решения?
3 Solutions collect form web for “«Список аргументов слишком длинный»: как мне с этим справиться, не меняя мою команду?”
В Linux максимальный объем пространства для аргументов команды равен 1/4-му количеству свободного пространства стека. Таким образом, решение заключается в увеличении объема пространства, доступного для стека.
Короткая версия: запустите что-то вроде
ulimit -s 65536
Более длинная версия: объем пространства, доступный для стека по умолчанию, составляет примерно 8192 КБ. Вы можете увидеть объем доступного пространства:
$ ulimit -s 8192
Выберите большее количество и установите объем свободного места для стека. Например, если вы хотите попытаться разрешить до 65536 КБ для стека, запустите это:
$ ulimit -s 65536
Возможно, вам придется поиграть с тем, насколько это необходимо, с использованием проб и ошибок. Во многих случаях это быстрое и грязное решение, которое xargs
вас от необходимости изменять команду и выработать синтаксис find
, xargs
и т. Д. (Хотя я понимаю, что для этого есть другие преимущества).
Я считаю, что это зависит от Linux. Я подозреваю, что это, вероятно, не поможет ни в одной другой операционной системе Unix (не тестировалось).
В этой статье журнала Linux вы найдете 4 решения. Только четвертое решение не связано с изменением команды:
Метод №4 предусматривает ручное увеличение количества страниц, выделенных в ядре для аргументов командной строки. Если вы посмотрите файл include / linux / binfmts.h, вы увидите следующее:
/* * MAX_ARG_PAGES defines the number of pages allocated for arguments * and envelope for the new program. 32 should suffice, this gives * a maximum env+arg of 128kB w/4KB pages! */ #define MAX_ARG_PAGES 32
Чтобы увеличить объем памяти, посвященный аргументам командной строки, вам просто нужно указать значение MAX_ARG_PAGES с более высоким номером. Как только это редактирование будет сохранено, просто перекомпилируйте, установите и перезагрузите новое ядро, как обычно.
На моей собственной тестовой системе мне удалось решить все мои проблемы, повысив это значение до 64. После обширного тестирования у меня не было проблемы с коммутатором. Это полностью ожидаемо, так как даже с
MAX_ARG_PAGES
установленным на 64, самая длинная возможная команда, которую я мог бы произвести, будет занимать только 256 Кбайт системной памяти – не очень сильно по сегодняшним системным стандартам.Преимущества метода №4 очевидны. Теперь вы можете просто запустить команду, как обычно, и она завершается успешно. Недостатки одинаково ясны. Если вы увеличите объем доступной памяти в командной строке за пределы доступной системной памяти, вы можете создать атаку DOS в своей собственной системе и вызвать ее сбой. В многопользовательских системах, в частности, даже небольшое увеличение может иметь значительное влияние, поскольку каждый пользователь выделяет дополнительную память. Поэтому всегда проверяйте широко в своей собственной среде, так как это самый безопасный способ определить, является ли метод №4 жизнеспособным вариантом для вас.
Я согласен с тем, что ограничение серьезно раздражает.
Вместо ls */*/*/*/*.jpg
попробуйте:
echo */*/*/*/*.jpg | xargs ls
xargs
(1) знает, каково максимальное количество аргументов в системе и разложит свой стандартный ввод, чтобы вызывать указанную командную строку несколько раз без каких-либо аргументов, чем этот предел, независимо от того, что это (вы также можете установить его ниже чем максимальная ОС, используя опцию -n
).
Например, предположим, что ограничение равно 3 аргументам, и у вас есть пять файлов. В этом случае xargs
выполнит ls
дважды:
-
ls 1.jpg 2.jpg 3.jpg
-
ls 4.jpg 5.jpg
Часто это идеально подходит, но не всегда – например, вы не можете полагаться на ls
(1), сортируя все записи для вас должным образом, потому что каждое отдельное ls
-invocation будет сортировать только подмножество записей, присвоенных ему xargs
,
Хотя вы можете ограничить предел, как это было предложено другими, все равно будет предел – и однажды ваша коллекция JPG снова перерастет ее. Вы должны подготовить свой сценарий (ы), чтобы иметь дело с бесконечным числом …