GNU/Linux >> Tutoriels Linux >  >> Linux

Comment provoquer l'erreur "Liste d'arguments trop longue" ?

Cette question a déjà des réponses ici :Qu'est-ce qui définit la taille maximale d'une commande à un seul argument ?

(3 réponses)
Fermé il y a 2 ans.

Contexte de la question :selon les spécifications POSIX, ARG_MAX est la longueur maximale des arguments de ligne de commande à exec() famille de fonctions. Ce qui m'amène à croire que c'est le vrai nombre d'arguments, mais cela n'a clairement pas fonctionné :

$ ulimit -s
8192
$ touch {1..18000}.jpg
$ rm *.jpg
$ 

De toute évidence, cela fonctionne bien, malgré sa longueur supérieure à 8192 éléments. Selon la réponse de D.W., le 8192 est censé être la taille en Ko. Il est donc clair que l'hypothèse précédente était fausse.

C'est là qu'intervient la vraie question :comment déterminer le nombre d'articles qui vont dépasser la limite de 8192 ko ? En d'autres termes, quel type de calcul dois-je effectuer pour m'assurer que *.jpg le type de glob se traduira par Argument list too long erreur ?

Veuillez noter qu'il ne s'agit pas d'un doublon de ce qui définit la taille maximale d'un argument de commande unique. Je connais getconf ARG_MAX et ulimit -s valeurs, ce n'est pas ma question. J'ai besoin de savoir comment générer suffisamment d'arguments dont la taille sera supérieure à la limite . En d'autres termes, je dois trouver un moyen d'obtenir l'erreur, pas de l'éviter.

Réponse acceptée :

Utilisation de getconf ARG_MAX pour générer une longue liste de x et appeler un utilitaire externe avec cela comme argument générerait une erreur "Liste d'arguments trop longue" :

$ /bin/echo $( perl -e 'print "x" x $ARGV[0]' "$(getconf ARG_MAX)" )
/bin/sh: /bin/echo: Argument list too long

L'environnement et la longueur de la chaîne /bin/echo seront inclus dans ce qui provoque l'erreur, nous pouvons donc essayer de trouver le plus grand nombre possible en soustrayant ceux-ci :

$ env
PATH=/usr/bin:/bin:/usr/sbin:/sbin:/usr/X11R6/bin:/usr/local/bin

(J'ai commencé ce shell avec env -i sh , donc il n'y a que le PATH variable dans l'environnement)

$ /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo"))' "$(getconf ARG_MAX)" )
sh: /bin/echo: Argument list too long

Encore trop longtemps. De combien ?

i=0
while ! /bin/echo $( perl -e 'print "x" x ($ARGV[0] - length($ENV{"PATH"}) - length("/bin/echo") - $ARGV[1])' "$(getconf ARG_MAX)" "$i" )
do
    i=$(( i + 1 ))
done

Cette boucle se termine pour i=8 .

Il y a donc quatre octets dont je ne peux pas tenir compte immédiatement (quatre des huit doivent être pour le nom du PATH variables d'environnement). Ce sont les terminateurs nuls pour les quatre chaînes PATH , la valeur de PATH , /bin/echo et la longue chaîne de x caractères.

En relation :Linux – Pourquoi faut-il autant de temps pour détecter une clé USB ?

Notez que chaque L'argument se termine par un caractère nul, donc plus vous avez d'arguments pour la commande, plus leur longueur combinée peut être courte.

Aussi, juste pour montrer l'effet d'un grand environnement :

$ export BIG=$( perl -e 'print "x" x $ARGV[0]' "$( getconf ARG_MAX )" )

$ /bin/echo hello
sh: /bin/echo: Argument list too long

$ /bin/echo
sh: /bin/echo: Argument list too long

Linux
  1. Comment Linux gère-t-il plusieurs séparateurs de chemins consécutifs (/home////nom d'utilisateur///fichier) ?

  2. Comment faire écho à un coup ! ?

  3. Pourquoi /bin/sh pointe-t-il vers /bin/dash et non /bin/bash ? ?

  4. bash :/bin/tar :liste d'arguments trop longue lors de la compression de nombreux fichiers avec tar

  5. Quand dois-je utiliser /dev/shm/ et quand dois-je utiliser /tmp/?

Comment réparer /bin/rm :impossible d'exécuter [Liste d'arguments trop longue]

Aucune raison d'avoir un Shebang pointant vers /bin/sh plutôt que /bin/bash ?

Linux – Fusionner /usr/bin et /usr/sbin dans /bin (gnu/linux) ?

Installer les binaires dans /bin, /sbin, /usr/bin et /usr/sbin, interactions avec --prefix et DESTDIR

Comment inverser une liste de mots dans une chaîne shell ?

Déplacement du contenu de /bin vers /usr/bin, possible d'annuler ?