9 votes

La restriction "liste d'arguments trop longue" s'applique-t-elle aux buildins shell ?

J'ai parcouru de nombreux postes sur Stack Overflow ainsi que sur quelques communautés connexes concernant le argument list too long et je ne parviens pas à déterminer clairement si la restriction de longueur s'applique ou non aux buildins shell.

Disons que je veux transmettre une très longue chaîne à une commande par l'intermédiaire de l'entrée standard :

string="a very long list of words ..."

Je peux dire :

# not using double quotes around $string is deliberate
printf '%s\n' $string | cmd ...

ou

cmd <<< $string

Ou même de l'envoyer à xargs :

printf '%s\n' $string | xargs cmd ...

Quelqu'un peut-il clarifier ce point ?

12voto

Charles Duffy Points 34134

Dans bash, la limitation de la longueur de la ligne de commande imposée par le système d'exploitation provoque l'erreur suivante argument list too long n'est pas appliquée aux buildins du shell.

Cette erreur est déclenchée lorsque le execve() syscall renvoie le code d'erreur E2BIG . Il n'y a pas de execve() impliqué lors de l'invocation d'un buildin, donc l'erreur ne peut pas avoir lieu.

Ainsi, les deux opérations que vous proposez sont sûres : cmd <<< "$string" écrit $string dans un fichier temporaire, ce qui ne nécessite pas qu'il soit transmis en tant qu'élément argv (ou variable d'environnement, qui est stocké dans le même pool d'espace réservé) ; et printf '%s\n' "$cmd" a lieu à l'intérieur de l'interpréteur de commandes, à moins que la configuration de l'interpréteur de commandes n'ait été modifiée, comme dans l'option enable -n printf pour utiliser une printf mise en œuvre.

3voto

Basile Starynkevitch Points 67055

Je n'arrive pas à savoir si la restriction de longueur s'applique aux buildins shell ou non.

Probablement pas, mais vous devriez vérifier le code source de votre version particulière de bash (puisqu'il s'agit d'un logiciel libre). Cependant, il y a évidemment une certaine limitation - que l'on espère plus importante - (en particulier parce que certains logiciels de la gamme de produits de l'entreprise ont été modifiés). malloc fait à l'intérieur bash pourrait échouer), mais vous obtiendrez alors un autre message d'erreur ou un autre comportement.

A ma connaissance, l'erreur "liste d'arguments trop longue" est donnée par execve(2) à défaut de E2BIG et les fonctions intégrées de bash ne le font pas. fork puis execve (comme le font les programmes externes invoquant des commandes).

En pratique, E2BIG pourrait apparaître avec quelques centaines de milliers d'octets (la limite exacte dépend du noyau et du système) mais je suppose que les builtins pourraient être utilisés sur plusieurs dizaines de mégaoctets (sur les ordinateurs de bureau d'aujourd'hui). Mais YMMV (puisque vous pourriez utiliser ulimit pour que votre coquille fasse un peu setrlimit(2) ...). Je ne recommanderai pas de manipuler des gigaoctets de données par le biais de buildins shell.

BTW, xargs(1) peut être utile, et vous pourriez même augmenter la limite (pour les E2BIG ) en recompilant votre noyau (et aussi par d'autres moyens, dans les noyaux récents). Il y a quelques années, c'était une forte motivation pour moi de recompiler les noyaux.

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