Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

[HS Debian] rm : liste d'arguments trop longue

26 réponses
Avatar
Steve
Bonsoir,

J'ai un r=C3=A9pertoire contenant 10G de donn=C3=A9es r=C3=A9parties en pet=
it fichier (genre=20
50 ko, donc =C3=A7a fait *beaucoup* de fichiers). Je d=C3=A9sire effacer to=
us les=20
fichiers. Mais :

$ rm *
bash: /bin/rm: Liste d'arguments trop longue
$ rm 3*
bash: /bin/rm: Liste d'arguments trop longue
$ rm 31*
bash: /bin/rm: Liste d'arguments trop longue
etc...
=2E
=2E
=46inalement
$ rm 32-20070322231 =C2=ABtab=C2=BB
Display all 5982 possibilities? (y or n)n
(me dis que c'est bon .., mais)
$ rm 32-20070322231*
bash: /bin/rm: Liste d'arguments trop longue
$ rm 32-20070322231 =C2=ABtab=C2=BB
Display all 600 possibilities? (y or n)n
$ rm 32-200703222311*
$=20
Enfin ! Donc le nombre d'arguments est au plus de 5982. Ce qui me m=C3=A8ne=
=C3=A0 me=20
poser deux questions :

1- quelle est le nombre maximal ? comment le trouver ?
2- comment m'en affranchir dans mon cas ?

Merci pour vos r=C3=A9ponses et bonne fin de semaine.
=2D-=20
steve

10 réponses

1 2 3
Avatar
Yannick P.
Cyril Roques a écrit :
le caractere * est remplacé par bash lui-meme donc quand tu fait ls 31*
bash execute reellement ls 31123 312334 31345 ...... c'est pour cela
qu'il t'envoi dans les choux donc quelque chose comme ls | grep ^31 |
xargs rm devrait fonctionner



Est-ce que ça ne peut pas être considéré comme un défaut (corrigible ?)
de rm ?
Je dois dire que je ne sais pas comment fonctionnent ses relations avec
le système de fichiers.


--
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
with a subject of "unsubscribe". Trouble? Contact
Avatar
Jacques L'helgoualc'h
Steve a écrit, samedi 24 mars 2007, à 08:15 :
Bonjour,



bonjour,

[...]
Question subsidiaire 2 : quelle est la longueur maximale d'un fichier ? N'y a
t-il pas une variable d'environnement s'y rapportant et qu'on peut modifier ?



Tu parles plutôt de la longueur d'un « nom de fichier » ? Ça dépend du
système de fichiers utilisé (et de l'OS). C'est facile à tester,

$ A=A;for((n=0;n<16;n++));do echo "2^$n A";touch "$A"||break;A="$A$A";done
2^0 A
2^1 A
2^2 A
2^3 A
2^4 A
2^5 A
2^6 A
2^7 A
2^8 A
touch: ne peut faire un touch sur `AAAAAAAA[...]AAAA': Nom de fichier trop long

donc en ext3 (sarge), la limite est entre 128 et 256 --- peut-être 255,
à cause du caractère NUL final ? La fin est laissée en exercice ;)

Il me semble qu'il peut aussi y avoir une limite sur la longueur totale
du chemin --- elle était assez basse dans le vieux standard iso9660 des
CD (avec aussi une limite à la profondeur de l'arbre, de mémoire 8 ou 9
niveaux).

Merci à tous pour vos réponses



de rien,
--
Jacques L'helgoualc'h


--
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
with a subject of "unsubscribe". Trouble? Contact
Avatar
Remi Vanicat
"Yannick P." writes:

Yannick P. a écrit :
Est-ce que ça ne peut pas être considéré comme un défaut (corrigible
?) de rm ?



Ou plutôt de Bash.



Non, enfin plutôt c'est tellement traditionnel sous Unix, depuis
tellement longtemps qu'on ne peut plus le changer, trop d'outils
dépendent de ce fonctionnement. d'ailleurs les autres shells font
pareil.

D'ailleurs un intérêt important de ce fonctionnement, c'est que si je
veux que mon script/application puisse être lancer sous la forme
"toto *" il me suffit de ne rien faire, bash/sh/tcsh/ksh/... le fait
pour moi.

--
Rémi Vanicat


--
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
with a subject of "unsubscribe". Trouble? Contact
Avatar
fra-duf-no-spam
Le 13596ième jour après Epoch,
écrivait:

Le vendredi 23 mars 2007 23:24, François TOURDE a écrit :
$ cd ..
$ rm -fr ton_répertoire
$ mkdir ton_répertoire



j'y avais pensé, mais je ne voulais pas le faire comme cela



Ah? C'est pourtant facile, non?

$ set -f



Je ne vois pas cette option dans « man set ». Que fait-elle ?



Elle ne semble pas être dans le man de bash, c'est bizarre. En gros,
elle empêche le développement des noms par le shell.

$ set -f
$ rm *

la commande rm est appelée avec le paramètre "*", et il se trouve
qu'elle sait gérer ça.

Tu aurais pû aussi faire:

$ rm *
Avatar
fra-duf-no-spam
Le 13596ième jour après Epoch,
François TOURDE écrivait:

Le 13596ième jour après Epoch,
écrivait:

Le vendredi 23 mars 2007 23:24, François TOURDE a écrit :
$ cd ..
$ rm -fr ton_répertoire
$ mkdir ton_répertoire



j'y avais pensé, mais je ne voulais pas le faire comme cela



Ah? C'est pourtant facile, non?

$ set -f



Je ne vois pas cette option dans « man set ». Que fait-elle ?



Elle ne semble pas être dans le man de bash, c'est bizarre. En gros,
elle empêche le développement des noms par le shell.

$ set -f
$ rm *

la commande rm est appelée avec le paramètre "*", et il se trou ve
qu'elle sait gérer ça.

Tu aurais pû aussi faire:

$ rm *



Tiens, après vérification, il semble que cela ne marche plus :(

Je suis pourtant quasiment sûr que rm était capable de faire
l'expansion lui-même... Ce qui empêchait d'effacer des fichiers c omme
'?', '*', et autres...

C'est promis, demain j'arrête ;)

--
La difficulté pour les célibataires c'est de déshabiller les femmes,
pour les maris c'est de les habiller.
Avatar
Yves Rutschle
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:

:~/try$ env | wc
24 24 1046

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

Environnement + Ligne = 1046 + 130020 = 131066

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

Environnement + Ligne = 1046 + 130000 = 131046

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

Nombre d'arguments:
:~/try2$ ( for i in `seq 1 32766`; do echo -n "a "; done ) > toto
:~/try2$ touch `cat toto`
:~/try2$ ( for i in `seq 1 32767`; do echo -n "a "; done ) > toto
:~/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
with a subject of "unsubscribe". Trouble? Contact
Avatar
Sylvain Sauvage
Steve, samedi 24 mars 2007, 08:15:57 CET

Bonjour,



’jour,

[...]
> Normal, la commande « ls 31* » met aussi les noms de
> fichiers dans la ligne de commande. Mon exemple était « ls
> », et, lui, il ne comporte que « ls » dans la ligne de
> commande.

Là je ne comprends pas très bien : « ls 31* » retour ne
moins de fichiers que juste « ls » non ? Mais après test,
effectivement ça marche.



Le problème n’est pas avec ce qui est « retourné » mais avec
ce qui est donné.
Comme l’a expliqué Yves dans le compte rendu de sa recherche de
la limite perdue, la limite concerne la taille de la ligne de
commande une fois qu’elle est « globée » (les joker s remplacés).
Dans 'ls | xargs rm', la ligne de commande est « ls », alors que
dans 'ls 31*', c’est « ls 31bla1 31bla2 ... », qui dà ©borde.
Ce que tu appelle « retourné » est ce qui est « affic hé », plus
précisément ce que ls envoie dans son flux de sortie standard. La
taille du flux n’est pas limitée (/dev/zero est un flux infin i).
Et c’est parce que la taille du flux n’est pas limità ©e que je
t’ai proposé d’utiliser un tube et xargs.

[...]
Question subsidiaire 2 : quelle est la longueur maximale d'un
fichier ?



Je suppose que tu veux connaître la longueur maximale d’un _ nom
de fichier. Tu peux trouver tout ça par là :
http://en.wikipedia.org/wiki/Comparison_of_file_systems
(d’ailleurs, si quelqu’un se sent motivé de traduire l a page pour
compléter la version française...)

Ça va de 8 octets à 4032 octets (reiserfs, mais ça corresp ond à
255 caractères).

Pour la taille maximale d’un fichier, ça va de quelques ki o à
l’infini (GPFS, pour les clusters).

N'y a t-il pas une variable d'environnement s'y
rapportant et qu'on peut modifier ?



Eh non.

--
Sylvain Sauvage
Avatar
fra-duf-no-spam
Le 13596ième jour après Epoch,
Yves Rutschle écrivait:

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.



[... Tout un tas de trucs et de machins ...]

Voilà voilà.



Excellente investigation ! Bravo pour ce compte-rendu tout à fait
complet. Il pleut, chez toi aussi, non? :)

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



Voilà, c'est bien ce que je pensais... Il pleut.

--
C'est par peur de la mort que je pense au suicide.
-+- Michel Blanc -+-
Avatar
Yves Rutschle
On Sat, Mar 24, 2007 at 05:25:10PM +0100, Sylvain Sauvage wrote:
Dans 'ls | xargs rm', la ligne de commande est « ls », alors que
dans 'ls 31*', c???est « ls 31bla1 31bla2 ... », qui déborde.



Au fait, au cours de ma recherche de ce matin, j'ai appris
un autre truc: xargs limite la taille de la ligne de
commande à 20k (ce qui correspond à ne prendre aucun risque,
comme vu ce matin), et cette limite est parametrable avec
-s. Une fois la limite atteinte, il lance une nouvelle
commande.

Y.


--
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
with a subject of "unsubscribe". Trouble? Contact
Avatar
Steve
> Voilà voilà.

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



je vois ;-)
--
steve
1 2 3