130 votes

Ligne de commande Bash et limite d'entrée

Y a-t-il une sorte de limite de caractères imposée en bash (ou dans d'autres shells) pour la longueur maximale d'une entrée? Si oui, quelle est cette limite de caractères?

Autrement dit, est-il possible d'écrire une commande en bash qui est trop longue pour être exécutée en ligne de commande? S'il n'y a pas de limite requise, existe-t-il une limite suggérée?

169voto

Jens Points 17702

La limite pour la longueur d'une ligne de commande n'est pas imposée par le shell, mais par le système d'exploitation. Cette limite est généralement de l'ordre de cent kilo-octets. POSIX désigne cette limite ARG_MAX et sur les systèmes conformes à POSIX, vous pouvez la consulter avec

$ getconf ARG_MAX    # Obtenir la limite d'argument en octets

Par exemple, sur Cygwin, cette limite est de 32000, et sur les différents BSDs et systèmes Linux que j'utilise, elle varie de 131072 à 2621440.

Si vous avez besoin de traiter une liste de fichiers dépassant cette limite, vous voudrez peut-être regarder l'utilitaire xargs, qui appelle un programme de manière répétée avec un sous-ensemble d'arguments ne dépassant pas ARG_MAX.

Pour répondre à votre question spécifique, oui, il est possible de tenter d'exécuter une commande avec une liste d'arguments trop longue. Le shell renverra une erreur avec un message indiquant "liste d'arguments trop longue".

Remarquez que l'entrée d'un programme (telle que lue sur stdin ou tout autre descripteur de fichier) n'est pas limitée (uniquement par les ressources disponibles du programme). Ainsi, si votre script shell lit une chaîne dans une variable, vous n'êtes pas limité par ARG_MAX. La restriction ne s'applique pas non plus aux commandes intégrées au shell.

54voto

Mike S Points 1065

D'accord, habitants. J'ai donc accepté les limites de longueur de la ligne de commande comme étant des évangiles depuis un certain temps. Alors, que faire de ses hypothèses? Naturellement, vérifiez-les.

J'ai une machine Fedora 22 à ma disposition (c'est-à-dire : Linux avec bash4). J'ai créé un répertoire avec 500 000 inodes (fichiers) dont chacun mesure 18 caractères de long. La longueur de la ligne de commande est de 9 500 000 caractères. Créé ainsi :

seq 1 500000 | while read digit; do
    touch $(printf "abigfilename%06d\n" $digit);
done

Et nous notons :

$ getconf ARG_MAX
2097152

Notez cependant que je peux faire ceci :

$ echo * > /dev/null

Mais cela échoue :

$ /bin/echo * > /dev/null
bash: /bin/echo: Argument list too long

Je peux exécuter une boucle for :

$ for f in *; do :; done

qui est une autre commande intégrée au shell.

Une lecture attentive de la documentation pour ARG_MAX indique, Longueur maximale de l'argument des fonctions exec. Cela signifie : Sans appeler exec, il n'y a pas de limitation de ARG_MAX. C'est pourquoi les commandes intégrées au shell ne sont pas limitées par ARG_MAX.

Et en effet, je peux faire un ls sur mon répertoire si ma liste d'arguments comporte 109948 fichiers, soit environ 2 089 000 caractères (à quelques variations près). Une fois que j'ajoute un fichier supplémentaire de 18 caractères, cependant, j'obtiens une erreur Liste d'arguments trop longue. Ainsi, ARG_MAX fonctionne comme annoncé : l'exécution échoue avec plus de ARG_MAX caractères dans la liste des arguments - incluant, il convient de le noter, les données d'environnement.

3voto

Paul Kenjora Points 226

Il y a une limite de tampon d'environ 1024. La lecture se bloquera simplement en plein collage ou entrée. Pour résoudre ce problème, utilisez l'option -e.

http://linuxcommand.org/lc3_man_pages/readh.html

-e utilise Readline pour obtenir la ligne dans un shell interactif

Modifiez votre lecture en "lecture -e" et le blocage ennuyeux de l'entrée de ligne disparaîtra.

0voto

Mark Lakata Points 3458

Autrefois, tcsh avait une limite de 1024 caractères par ligne de commande, ce qui rendait les choses difficiles si vous aviez un très long $PATH. J'ai été contraint de reconstruire une version privée de tcsh avec la taille du tampon augmentée pour permettre aux utilisateurs d'avoir des paramètres de $PATH longs. C'était il y a 2 décennies. C'est à ce moment-là que j'ai arrêté d'utiliser tcsh et suis passé à zsh qui n'avait pas cette limitation. Maintenant, je me contente d'utiliser simplement le vieux bash car il est suffisant.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X