Если список аргументов слишком длинный (помните, что * расширяет до списка всех файлов, которые соответствуют глобусу), вы можете обойти его, используя eg IFS="\n" for file in /src/*; do mv "$file" /dst/; doneили rsync -a /src/ /dst/.
DopeGhoti
Ответы:
18
Это сильно зависит от системы и версии, количества и размера аргументов, а также от количества и размера имен переменных среды.
Традиционно в Unix ограничение (как сообщалось getconf ARG_MAX) было более или менее на совокупный размер:
Длина строки аргумента (включая завершающую '\0')
Длина массива указателей на эти строки, поэтому обычно 8 байтов на аргумент в 64-битной системе
Длина строк окружения (включая завершающую '\0'), при этом строка окружения условно выглядит примерно так var=value.
Длина массива указателей на эти строки, поэтому обычно 8 байтов на аргумент в 64-битной системе
Принимая во внимание, что это cpтакже считается аргументом (это первый аргумент).
В Linux это зависит от версии. Поведение там изменилось недавно, когда это уже не фиксированное пространство.
При проверке в Linux 3.11 getconf ARG_MAXтеперь сообщается о четверти ограничения, установленного для размера стека, или 128 кБ, если это меньше 512 кБ).
Это ограничение на совокупный размер аргумента и строк среды и некоторые накладные расходы (я подозреваю, из-за рассмотрения выравнивания на границах страницы). Размер указателей не учитывается.
В поисках лимита я получаю:
$ /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
Максимальный совокупный размер до взлома в этом случае:
Теперь это не значит, что вы можете передать 1 миллион пустых аргументов. В 64-битной системе 1 миллион пустых аргументов составляет список указателей размером 8 МБ, что превышает размер моего стека в 4 МБ.
(Вы заметите, что это не ошибка E2BIG. Я не уверен, в какой момент процесс там будет убит, хотя, если это в execveсистемном вызове или позже).
Также обратите внимание (все еще в Linux 3.11), что максимальный размер одного аргумента или строки среды составляет 128 кБ, независимо от размера стека.
$ /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
Подскажите пожалуйста, как вы пришли к 164686номеру? то есть как вы рассчитали, что последовательность будет меньше 2097152размера ARG_MAX?
Сергей Колодяжный
14
Это будет зависеть от значения ARG_MAX, которое может меняться в разных системах. Чтобы узнать значение для запуска вашей системы (в качестве примера показан мой результат):
$ getconf ARG_MAX
2097152
Это не имеет ничего общего с cpвашей оболочкой, это ограничение, налагаемое ядром, оно не будет выполнять exec()команды ( ), если их аргументы длиннее, чем ARG_MAX. Таким образом, если длина списка аргументов, который вы cpуказали, превышает ARG_MAX, cpкоманда вообще не будет выполняться.
Чтобы ответить на ваш главный вопрос, не cpбудет обрабатывать файлы, так как он никогда не будет выполнен с таким количеством аргументов. Я должен также упомянуть, что это зависит не от количества аргументов, а от их длины. Вы можете предположить, что такая же проблема возникает с очень небольшим, но очень длинным именем файла.
Способ обойти эти ошибки - запустить вашу команду в цикле:
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
илиrsync -a /src/ /dst/
.Ответы:
Это сильно зависит от системы и версии, количества и размера аргументов, а также от количества и размера имен переменных среды.
Традиционно в Unix ограничение (как сообщалось
getconf ARG_MAX
) было более или менее на совокупный размер:'\0'
)'\0'
), при этом строка окружения условно выглядит примерно такvar=value
.Принимая во внимание, что это
cp
также считается аргументом (это первый аргумент).В Linux это зависит от версии. Поведение там изменилось недавно, когда это уже не фиксированное пространство.
При проверке в Linux 3.11
getconf ARG_MAX
теперь сообщается о четверти ограничения, установленного для размера стека, или 128 кБ, если это меньше 512 кБ).(
zsh
синтаксис ниже):Это ограничение на совокупный размер аргумента и строк среды и некоторые накладные расходы (я подозреваю, из-за рассмотрения выравнивания на границах страницы). Размер указателей не учитывается.
В поисках лимита я получаю:
Максимальный совокупный размер до взлома в этом случае:
Теперь это не значит, что вы можете передать 1 миллион пустых аргументов. В 64-битной системе 1 миллион пустых аргументов составляет список указателей размером 8 МБ, что превышает размер моего стека в 4 МБ.
(Вы заметите, что это не ошибка E2BIG. Я не уверен, в какой момент процесс там будет убит, хотя, если это в
execve
системном вызове или позже).Также обратите внимание (все еще в Linux 3.11), что максимальный размер одного аргумента или строки среды составляет 128 кБ, независимо от размера стека.
источник
164686
номеру? то есть как вы рассчитали, что последовательность будет меньше2097152
размера ARG_MAX?Это будет зависеть от значения ARG_MAX, которое может меняться в разных системах. Чтобы узнать значение для запуска вашей системы (в качестве примера показан мой результат):
Это не имеет ничего общего с
cp
вашей оболочкой, это ограничение, налагаемое ядром, оно не будет выполнятьexec()
команды ( ), если их аргументы длиннее, чемARG_MAX
. Таким образом, если длина списка аргументов, который выcp
указали, превышает ARG_MAX,cp
команда вообще не будет выполняться.Чтобы ответить на ваш главный вопрос, не
cp
будет обрабатывать файлы, так как он никогда не будет выполнен с таким количеством аргументов. Я должен также упомянуть, что это зависит не от количества аргументов, а от их длины. Вы можете предположить, что такая же проблема возникает с очень небольшим, но очень длинным именем файла.Способ обойти эти ошибки - запустить вашу команду в цикле:
источник
C
могут иметь проблемы с ARG_MAX и действительно длинными именами файлов?