(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.
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