¿Existe algún tipo de límite de caracteres impuesto en bash (u otros shells) por cuánto tiempo puede durar una entrada? Si es así, ¿cuál es ese límite de caracteres?
Es decir, ¿es posible escribir un comando en bash que sea demasiado largo para que se ejecute la línea de comandos? Si no hay un límite obligatorio, ¿hay un límite sugerido?
bash
shell
unix
command-line-arguments
Derek Halden
fuente
fuente
Respuestas:
El límite de la longitud de una línea de comando no lo impone el shell, sino el sistema operativo. Este límite suele estar en el rango de cien kilobytes. POSIX denota este límite
ARG_MAX
y en sistemas compatibles con POSIX puede consultarlo con$ getconf ARG_MAX # Get argument limit in bytes
Por ejemplo, en Cygwin es 32000, y en los diferentes BSD y sistemas Linux que utilizo es entre 131072 y 2621440.
Si necesita procesar una lista de archivos que exceden este límite, es posible que desee ver la
xargs
utilidad, que llama a un programa repetidamente con un subconjunto de argumentos que no excedeARG_MAX
.Para responder a su pregunta específica, sí, es posible intentar ejecutar un comando con una lista de argumentos demasiado larga. El shell producirá un error con un mensaje junto con "lista de argumentos demasiado larga".
Tenga en cuenta que la entrada a un programa (como se lee en stdin o cualquier otro descriptor de archivo) no está limitada (solo por los recursos del programa disponibles). Entonces, si su script de shell lee una cadena en una variable, no está restringido por
ARG_MAX
. La restricción tampoco se aplica a los shell-builtins.fuente
cmd <<< "$LONG_VAR"
y el valor LONG_VAR excedió el límite, ¿fallaría mi comando?LONG_VAR
se pasa en stdin, y eso se hace completamente en el shell; no se expande como un argumento paracmd
, por lo que el límite ARG_MAX para fork () / exec () no entra en juego. Es fácil probarlo usted mismo: cree una variable con contenido superior a ARG_MAX y ejecute su comando.blah="$(cat /home/schwager/Music/Recordings/20090420\ 131623.m4a)"; cat <<< $blah >/dev/null
. No tenga en cuenta ningún error.xargs
en MacOS 10.12.6 límites de lo mucho que trata de poner en unaexec()
aARG_MAX - 4096
. Así que el uso de scriptsxargs
podría funcionar, hasta que un día alguien ponga demasiadas cosas en el entorno. Corriendo con esto ahora (solucionarlo con :)xargs -s ???
.Ok, habitantes. Así que he aceptado los límites de longitud de la línea de comando como evangelio durante bastante tiempo. Entonces, ¿qué hacer con las suposiciones de uno? Naturalmente, compruébalos.
Tengo una máquina Fedora 22 a mi disposición (es decir, Linux con bash4). He creado un directorio con 500.000 inodos (archivos) cada uno de 18 caracteres de largo. La longitud de la línea de comando es de 9.500.000 caracteres. Creado así:
seq 1 500000 | while read digit; do touch $(printf "abigfilename%06d\n" $digit); done
Y notamos:
Sin embargo, tenga en cuenta que puedo hacer esto:
$ echo * > /dev/null
Pero esto falla:
$ /bin/echo * > /dev/null bash: /bin/echo: Argument list too long
Puedo ejecutar un bucle for:
$ for f in *; do :; done
que es otro shell incorporado.
Lectura cuidadosa de la documentación para
ARG_MAX
estados, longitud máxima de argumento para las funciones ejecutivas . Esto significa: sin llamarexec
, no hayARG_MAX
limitación. Por lo tanto, explicaría por qué los elementos integrados de shell no están restringidos porARG_MAX
.Y, de hecho, puedo
ls
usar mi directorio si mi lista de argumentos tiene 109948 archivos, o aproximadamente 2,089,000 caracteres (más o menos). Sin embargo, una vez que agrego un archivo de nombre de archivo de 18 caracteres más, aparece un error de lista de argumentos demasiado larga . TambiénARG_MAX
funciona como se anuncia: el ejecutivo está fallando con más deARG_MAX
caracteres en la lista de argumentos, incluidos, debe tenerse en cuenta, los datos del entorno.fuente
for f in *; do echo $f; done
no se bifurca en absoluto (todas las funciones internas). Así que no sé si un combo find-xargs será más rápido; no ha sido probado. De hecho, no sé cuál es el conjunto de problemas del OP. Quizásfind /path/to/directory
no le sea útil porque devolverá el nombre de la ruta del archivo. Quizás le guste la simplicidad de unfor f in *
bucle. Independientemente, la conversación es sobre el límite de entrada de línea, no sobre la eficiencia. Así que sigamos en el tema, que se refiere a la longitud de la línea de comandos.Hay un límite de búfer de algo así como 1024. La lectura simplemente se colgará a mitad de pegado o entrada. Para resolver esto, use la opción -e.
http://linuxcommand.org/lc3_man_pages/readh.html
-usamos Readline para obtener la línea en un shell interactivo
Cambie su lectura a read -e y el molesto bloqueo de entrada de línea desaparecerá.
fuente
read
: "Es decir, ¿es posible escribir un comando en bash que sea demasiado largo para que se ejecute la línea de comandos?"bash --noediting
, y en el nuevo indicador intente ejecutar el comandoecho somereallylongword
, donde una palabra realmente larga tiene más de 4090 caracteres. Probado en Ubuntu 18.04, la palabra se truncó, por lo que obviamente tiene algo que ver con que Readline no esté habilitado.