On Fri, Mar 23, 2007 at 11:24:32PM +0100, François TOURDE wrote:
> > 1- quelle est le nombre maximal ? comment le trouver ?
> 
> Je ne sais pas le max, mais ça doit être marqué dans bash, non? :)

Attention, la curiosité est un défaut dangereux qui peut
vous emmener à des endroits que vous n'imaginiez pas.

Or donc, je me dis que j'allais trouver la limite dans le
code de bash.

Manque de bol, bash gère les paramètres comme des listes
chainées. Lorsqu'il y a expansion (de variables, de 'globs'
comme * en listes de fichiers, etc) il crée de nouveaux
éléments dans la liste. Toute la liste est ensuite passée à
execve sous forme d'un tableau de chaînes (argc, argv)[1]. À
aucun moment bash ne travaille sur la chaîne d'entrée
complète.

Conclusion 1: Bash n'a aucune limite de taille de ligne de
commande.

Bon, faut regarder execve alors. 

Dans glibc, on se rend compte que la libc fait quelques
vérifications sur les paramètres, mais globalement ne fait
que passer le argc et argv au noyau[2].

Bon, faut regarder dans le noyau alors.

Bingo: execve dans le noyau[3] additionne le nombre
d'arguments et vérifie qu'il soit inférieur à
(PAGE_SIZE*MAX_ARGPAGES-4)/4, soit 32767, puis il additionne
la taille de tous les arguments et de l'environnement et
vérifie qu'il soit inférieur à (PAGE_SIZE*MAX_ARGPAGES-4),
soit 131068.

Conclusion 2: La limitation est le fait de Linux, le
comportement de Bash devrait donc être différent sur Cygwin
ou BSD.

Conclusion 3: Linux limite le nombre d'arguments à 32767 et
la longueur totale des arguments plus de l'environnement à
131068 octets.

Vérification expérimentale:

[EMAIL PROTECTED]:~/try$ env | wc
     24      24    1046

Taille maximum de ligne de commande:
[EMAIL PROTECTED]:~/try$ for i in `seq 1 13002`; do touch `printf "%09d" $i`; 
done
[EMAIL PROTECTED]:~/try$ ls | wc
  13002   13002  130020
[EMAIL PROTECTED]:~/try$ rm *
bash: /bin/rm: Argument list too long

Environnement + Ligne = 1046 + 130020 = 131066

[EMAIL PROTECTED]:~/try$ for i in `seq 1 13000`; do touch `printf "%09d" $i`; 
done
[EMAIL PROTECTED]:~/try$ ls | wc
  13000   13000  130000
[EMAIL PROTECTED]:~/try$ rm *
[EMAIL PROTECTED]:~/try$ 

Environnement + Ligne = 1046 + 130000 = 131046

(apparement je me suis trompé dans une limite, c'est un peu
moins que 131068)

Nombre d'arguments:
[EMAIL PROTECTED]:~/try2$ ( for i in `seq 1 32766`; do echo -n "a "; done ) > 
toto
[EMAIL PROTECTED]:~/try2$ touch `cat toto`
[EMAIL PROTECTED]:~/try2$ ( for i in `seq 1 32767`; do echo -n "a "; done ) > 
toto
[EMAIL PROTECTED]:~/try2$ touch `cat toto`
bash: /usr/bin/touch: Argument list too long


Voilà voilà.

Y. --  Oh, bah, on s'est bien amusés.

[1] bash:execute_cmd.c:shell_execve()
[2] glibc:sysdeps/unix/sysv/linux/execve.c
[3] linux-2.6.14:fs/exec.c:do_execve() et copy_strings()


-- 
Lisez la FAQ de la liste avant de poser une question :
http://wiki.debian.net/?DebianFrench   
Vous pouvez aussi ajouter le mot ``spam'' dans vos champs "From" et
"Reply-To:"

To UNSUBSCRIBE, email to [EMAIL PROTECTED]
with a subject of "unsubscribe". Trouble? Contact [EMAIL PROTECTED]

Répondre à