Відповіді:
Це сильно залежить від системи та версії, від кількості та розміру аргументів, а також від кількості та розміру імен змінних середовища.
Традиційно на Unix ліміт (як повідомлялося getconf ARG_MAX
) був більшим чи меншим щодо кумулятивного розміру:
'\0'
)'\0'
), рядок середовища - за умовою, щось подібне var=value
.Маючи на увазі, що cp
також вважається аргументом (це перший аргумент).
Для Linux це залежить від версії. Поведінка там нещодавно змінилася там, де це вже не фіксований простір.
Перевіряючи Linux 3.11, getconf ARG_MAX
тепер повідомляється чверть обмеження, встановленого на розмір стека, або 128 КБ, якщо це менше 512 КБ).
( zsh
синтаксис нижче):
$ limit stacksize
stacksize 8MB
$ getconf ARG_MAX
2097152
$ limit stacksize 4M
$ getconf ARG_MAX
1048576
Цей ліміт визначається за сукупним розміром аргументів та рядків середовища та деякими накладними (я підозрюю, що враховується вирівнювання на межі сторінки). Розмір покажчиків не враховується.
Шукаючи ліміт, я отримую:
$ /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
Максимальний накопичувальний розмір перед розривом у такому випадку становить:
$ (env _=/bin/true x=;print -l /bin/true {1..164686}) | wc -c
1044462
Тепер це не означає, що ви можете передати 1 мільйон порожніх аргументів. У 64-бітовій системі 1 мільйон порожніх аргументів складають список вказівників 8 МБ, що буде вище мого стека на рівні 4 Мбіт.
$ IFS=:; /bin/true ${=${(l.1000000..:.)${:-}}}
zsh: killed /bin/true ${=${(l.1000000..:.)${:-}}}
(ви помітили, що це не помилка 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?
Це буде залежати від значення ARG_MAX, яке може змінюватися між системами. Щоб дізнатись значення для запуску вашої системи (показавши результат на шахті як приклад):
$ getconf ARG_MAX
2097152
Це не має нічого спільного з cp
вашою оболонкою, це обмеження, накладене ядром, воно не буде виконувати ( exec()
) команди, якщо їх аргументи довші ніж ARG_MAX
. Отже, якщо довжина списку аргументів, яку ви надали cp
, більша, ніж ARG_MAX, cp
команда взагалі не запуститься.
Тоді, щоб відповісти на ваше головне запитання, cp
обробка файлів не буде, оскільки вона ніколи не буде виконана з такою кількістю аргументів. Слід також зазначити, що це залежить не від кількості аргументів, а від їх тривалості. Можливо, у вас може виникнути однакова проблема з дуже невеликими, але дуже довгими іменами файлів.
Спосіб подолання цих помилок полягає у запуску команди в циклі:
for file in /src/*; do cp "$file" /dst/; done
C
можуть мати проблеми з ARG_MAX та дійсно довгими іменами?
IFS="\n" for file in /src/*; do mv "$file" /dst/; done
абоrsync -a /src/ /dst/
.