Предел символов в командной строке Linux
Я передаю переменную в сценарий в командной строке. Каков предел символов команды? например:
$ MyScript reallyreallyreally. reallyreallyreallylongoption
Ограничение, накладываемое оболочкой / ОС, обычно очень велико — обычно один или двести тысяч символов.
getconf ARG_MAX даст вам максимальный предел ввода для команды. В системе Debian у меня в настоящее время открыт терминал с возвратом 131072, что составляет 128 * 1024. Ограничение уменьшается вашими переменными среды, как будто моя память служит мне правильно, они передаются оболочкой в той же структуре, хотя в большинстве случаев это займет всего несколько сотен символов. Чтобы найти аппроксимацию этого значения, запустите env | wc -c — это предлагает 325 символов в данный момент на этом входе в систему на этом компьютере.
Сценарии, вероятно, разрешают эту полную длину, но не исключено, что другие утилиты наложат свои собственные ограничения либо намеренно, либо из-за проблем проектирования. Также могут быть искусственные ограничения на длину отдельного аргумента в длинной командной строке и / или на длину пути к файлу.
В моей системе getconf ARG_MAX выдает 2097152, но максимальная длина аргумента, которую я могу передать, по-прежнему составляет 131071 (и мне не нужно вычитать размер среды).
Также помните это xargs и даже find -exec ваши друзья, когда имеют дело с гигантскими списками аргументов.
@Dennis: значение, возвращаемое на getconf уровне ядра, я думаю. Возможно, bash устанавливает нижний предел своей конструкцией / конфигурацией? Кроме того, я знаю об этом некоторое время назад, так что может случиться так, что в последнее время все немного изменилось, хотя это не та область, в которой я ожидаю увидеть много движения, за исключением новых экспериментальных оболочек.
Я получаю те же результаты ksh , zsh , dash , fish и Bash 3 , как я сделал в Bash 4. Сообщение об ошибке fish может быть информативным: «рыба: Общий размер аргумента и окружения списков (130Kb) превышает предельное значение операционной системы в 2.0MB «. Тем не менее, set | wc -c это 306317 и env | wc -c 2507, которые не учитывают разницу. Я не знаю, что еще считается.
ARG_MAX действительно ограничивает общий размер командной строки и среды, но вы сталкиваетесь с дополнительным ограничением: один аргумент не должен быть длиннее, чем MAX_ARG_STRLEN (который, к сожалению, жестко задан как 131072).
Скомпилируйте ядро, чтобы увеличить максимальную длину командной строки
В продолжение https://stackoverflow.com/questions/14176089/system-command-line-max-length-in-perl, в котором говорится, что максимальная длина аргументов exec/ командной строки контролируется ARG_MAX . Поэтому я хочу увеличить максимальную длину такой командной строки, и кажется, что перекомпиляция ядра — единственный вариант. Хорошо. Однако мой вопрос по ARG_MAX , потому что все говорят, что это тот, который должен быть увеличен, но я прочитал с http://www.in-ulm.de/~mascheck/various/argmax/#linux, что, ARG_MAX не используется в самом коде ядра до 2.6.23. Сообщение Linux 2.6.23, ARG_MAX не зашиты больше. Так ARG_MAX не используется или нет? Как увеличить максимальную длину для аргументов exec/ командной строки? потому что моя максимальная длина командной строки ограничена некоторым меньшим значением, чем я предпочитаю. Спасибо
1 ответ 1
Поскольку Linux-2.6.23 ARG_MAX не обязательно предварительно определенная константа, общий размер аргументов разрешаются составлять до 1/4 от размера стека (см ulimit -s размер стека в Кб, но /proc/1/limits более определенны). Однако ARG_MAX предназначен не только для аргументов процесса, он также содержит переменные среды, которые вам, возможно, придется учитывать. POSIX определяет, что означает ARG_MAX , и приемлемый нижний предел _POSIX_ARG_MAX 4096). Его статическое значение (исторически) доступно через #define в системных заголовках, а также оно устанавливается в заголовочных файлах ядра Linux. Его эффективное значение доступно с помощью sysconf() или getconf ARG_MAX из командной строки. Если вы проверите заголовки glibc ( sys/param.h ), вы увидите это:
/* The kernel headers defines ARG_MAX. The value is wrong, though. */ #ifdef __undef_ARG_MAX # undef ARG_MAX # undef __undef_ARG_MAX #endif
Это из glibc-2.17, это появилось около 2.11 (2009), первая поддержка для этих дат — 2.8 (2008), но до 2.14 (2011) была ошибка в вышеупомянутой логике, которая мешала ему работать должным образом. Цель состоит в том, чтобы убедиться, что ARG_MAX не определен, если он не является константой, поэтому программы должны полагаться на sysconf() . (Даже если он определен, это может быть только нижний гарантированный предел, и программы должны использовать sysconf() для определения верхних пределов переменной, см. sysconf(3) ) Вы можете проверить, что видит ваш компилятор C (только синтаксис gcc , bash / zsh ):
$ gcc -E -dM -x c <(echo "#include ") | fgrep ARG #define ARG_MAX 131072 #define NCARGS ARG_MAX #define _POSIX_ARG_MAX 4096
Приведенный выше вывод получен из старой системы (2.6.27), в которой есть поддержка ядра, но не полная среда выполнения (поддержка glibc). Если вы не видите строки ARG_MAX то это не предопределенный предел, и вы должны использовать (sysconf) getconf ARG_MAX :
Это из системы linux-2.6.37/glib-2.13 с более высокими лимитами. Обратите внимание на последнюю строку вывода, xargs умолчанию (время сборки) до «разумного» предела, возможно, в случае, если какой-либо из процессов, которые он запускает, не способен обрабатывать очень большие значения. Вы можете изменить это во время выполнения с опцией -s . Кроме того, если у вас действует ulimit -s , эти цифры могут быть ниже. Это должно работать правильно, начиная с findutils-4.3.9 (2007). Смотрите также: http://www.gnu.org/software/coreutils/faq/coreutils-faq.html#Argument-list-too-long Чтобы проверить Perl:
% perl -MPOSIX -e 'print ARG_MAX . "\n"'; 131072
% perl -MPOSIX -e 'print ARG_MAX . "\n"'; Your vendor has not defined POSIX macro ARG_MAX, used at -e line 1
- Если вы работаете с ядром, выпущенным после 2.6.23, ядро разрешит передавать большие размеры при создании процесса. Это необходимое, но не достаточное условие.
- Родительский процесс не должен применять какие-либо неверные ограничения времени выполнения (например, с жестко запрограммированным ARG_MAX ), вместо этого он должен проверять коды ошибок exec() E2BIG и должен использовать sysconf(_SC_ARG_MAX) при необходимости.
- Дочерний процесс не должен применять какие-либо неправильные ограничения времени выполнения, в частности его код запуска, который обрабатывает ядро, при условии, что параметры не должны иметь неправильных жестко заданных ограничений (например, при настройке argc , argc , области среды для использования во время выполнения). Обычно это делается в libc (glibc).
- Для родителей и детей вам также может понадобиться настроить и собрать поддержку времени из libc (или эквивалентную). Для glibc для этого требуется как минимум glibc-2.8 (хотя должна быть возможность обойти его, он может быть не простым и не чистым)
Проблемной комбинацией является обновленное (linux> = 2.6.23) ядро, но отсутствует или подозревается поддержка glibc (glibc
Если вы работаете с более старым ядром, сначала убедитесь, что ваш поставщик не перенес эту функцию обратно. В противном случае вы можете в принципе изменить ограничение ядра и перекомпилировать, но вам также может понадобиться изменить хотя бы некоторые системные заголовки или исходный код для рабочей поддержки.
Программы должны иметь возможность обрабатывать произвольные значения, но это не всегда так: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/limits.h.html
- Предел зависит от имени пути.
- Предел различается между компиляцией и машинами времени выполнения.
Bash command line and input limit
Is there some sort of character limit imposed in bash (or other shells) for how long an input can be? If so, what is that character limit? I.e. Is it possible to write a command in bash that is too long for the command line to execute? If there is not a required limit, is there a suggested limit?
The input limit is very different from the OS-level argument limit (note that some things other than arguments, such as environment variables, also apply towards that one). The generated command passed to the operating system can have more or fewer characters than the shell command that generated it.
4 Answers 4
The limit for the length of a command line is not imposed by the shell, but by the operating system. This limit is usually in the range of hundred kilobytes. POSIX denotes this limit ARG_MAX and on POSIX conformant systems you can query it with
$ getconf ARG_MAX # Get argument limit in bytes
E.g. on Cygwin this is 32000, and on the different BSDs and Linux systems I use it is anywhere from 131072 to 2621440.
If you need to process a list of files exceeding this limit, you might want to look at the xargs utility, which calls a program repeatedly with a subset of arguments not exceeding ARG_MAX .
To answer your specific question, yes, it is possible to attempt to run a command with too long an argument list. The shell will error with a message along «argument list too long».
Note that the input to a program (as read on stdin or any other file descriptor) is not limited (only by available program resources). So if your shell script reads a string into a variable, you are not restricted by ARG_MAX . The restriction also does not apply to shell-builtins.
Командная строка Bash и ограничение ввода
есть ли какой-то предел символов, наложенный в bash (или других оболочках), как долго может быть вход? Если да, то каков предел персонажа?
т. е. Можно ли написать команду в bash, которая слишком длинна для выполнения командной строки? Если нет требуемого предела, есть ли предлагаемый предел?
3 ответов
ограничение длины командной строки накладывается не оболочкой, а операционной системой. Этот предел обычно находится в пределах ста килобайт. POSIX обозначает этот предел ARG_MAX и в системах, соответствующих POSIX, вы можете запросить его с помощью
$ getconf ARG_MAX # Get argument limit in bytes
например. на Cygwin это 32000, а на разных системах BSDs и Linux, которые я использую, это где-то от 131072 до 2621440.
Если вам нужно обработать список файлов, превышающих это ограничение, вы можете посмотри xargs утилита, которая вызывает программу повторно с подмножеством аргументов, не превышающим ARG_MAX .
чтобы ответить на ваш конкретный вопрос, да, можно попытаться выполнить команду слишком длинный список аргументов. Оболочка будет ошибаться с сообщением «список аргументов слишком длинный».
отметим, что вход программе (как читается на stdin или любом другом файловом дескрипторе) является не limited (только по доступной программе ресурсы.) Поэтому, если ваш сценарий оболочки считывает строку в переменную, вы не ограничены ARG_MAX .
ОК, Обитатели. Поэтому я принял ограничения длины командной строки как Евангелие в течение некоторого времени. Так что же делать со своими предположениями? Естественно-проверьте их.
в моем распоряжении есть машина Fedora 22 (что означает: Linux с bash4). Я создал каталог с 500 000 объектов (файлов) в каждом из 18 знаков. Длина командной строки составляет 9,500,000 символов. Создано таким образом:
seq 1 500000 | while read digit; do touch $(printf "abigfilename%06d\n" $digit); done
Примечание однако I может сделать это:
$ /bin/echo * > /dev/null bash: /bin/echo: Argument list too long
я могу запустить цикл for:
который является еще одной оболочкой.
внимательное чтение документация ARG_MAX государства максимальная длина аргумента для функций exec. Это означает: без вызова exec нет ARG_MAX ограничения. Таким образом, это объясняет, почему встроенные оболочки не ограничены ARG_MAX .
и действительно, я могу!—9—> мой каталог, если мой список аргументов составляет 109948 файлов или около 2,089,000 символов (плюс-минус). Как только я добавлю еще один 18-символьный файл с именем файла, я получу список аргументов слишком длинный ошибка. Так что ARG_MAX работает как объявлено: exec терпит неудачу с более чем ARG_MAX символы в списке аргументов-включая, следует отметить, данные среды.
существует ограничение буфера примерно 1024. Чтение будет просто висеть в середине вставки или ввода. Чтобы решить эту проблему, используйте опцию-e.
— e используйте Readline для получения строки в интерактивной оболочке
измените чтение на чтение-e, и раздражающий ввод строки исчезнет.