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

vider un répertoire

18 réponses
Avatar
Benoit Izac
Bonjour,

Je cherche à vider le répertoire $D de tout ce qu'il contient. Je
considère que le propriétaire de son contenu (pas forcément du
répertoire lui-même) est le même que celui qui lance la commande. Je ne
souhaite utiliser que des commandes POSIX.

Je ne vois qu'une solution :
% (cd $D && find . ! -name . -prune -exec rm -fr -- {} +)

Fonctionne-t-elle dans tous les cas ?
En existe-t-il d'autres ?

Merci.
--
Benoit Izac

10 réponses

1 2
Avatar
ALain Montfranc
Benoit Izac a écrit
Bonjour,

Je cherche à vider le répertoire $D de tout ce qu'il contient. Je
considère que le propriétaire de son contenu (pas forcément du
répertoire lui-même) est le même que celui qui lance la commande. Je ne
souhaite utiliser que des commandes POSIX.

Je ne vois qu'une solution :
% (cd $D && find . ! -name . -prune -exec rm -fr -- {} +)


le cd $D est inutile find $D ... marchera et tu peux remplacer le -exec
par un xargs (avec l'option -0 bien sur et un print0 dans le find)

De plus quel interet de descendre dans le repertoire puisque tu fais un
rm recursif ?

Rajoute donc un maxdepth dans le find...

Fonctionne-t-elle dans tous les cas ?
En existe-t-il d'autres ?



Pourquoi pas un rm -rf $D && mkdir $D ?

Avatar
Benoit Izac
Bonjour,

le 10/03/2007 à 17:25, ALain Montfranc a écrit dans le message
:

Je cherche à vider le répertoire $D de tout ce qu'il contient. Je
considère que le propriétaire de son contenu (pas forcément du
répertoire lui-même) est le même que celui qui lance la commande. Je ne
souhaite utiliser que des commandes POSIX.

Je ne vois qu'une solution :
% (cd $D && find . ! -name . -prune -exec rm -fr -- {} +)


le cd $D est inutile find $D ... marchera et tu peux remplacer


Non car mon « ! -name . » ne fonctionnera plus.

le -exec par un xargs (avec l'option -0 bien sur et un print0 dans le
find)


-print0 n'est pas POSIX. xargs -0 non plus.


De plus quel interet de descendre dans le repertoire puisque tu fais
un rm recursif ?


Je ne descends pas dedans puisque j'utilise « -prune ».

Rajoute donc un maxdepth dans le find...


-maxdepth n'est pas POSIX.

Fonctionne-t-elle dans tous les cas ?
En existe-t-il d'autres ?



Pourquoi pas un rm -rf $D && mkdir $D ?


Pour au moins deux raisons :
- cela risque de changer les permissions qu'avait initialement $D ;
- ça ne fonctionnera pas si tu n'es pas propriétaire de $D (cas de
$D avec le sticky bit).

--
Benoit Izac


Avatar
Jean-Rene David
* ALain Montfranc [2007.03.10 16:25]:
Benoit Izac a écrit
Je ne souhaite utiliser que des commandes POSIX.

Je ne vois qu'une solution :
% (cd $D && find . ! -name . -prune -exec rm -fr -- {} +)


le cd $D est inutile find $D ... marchera et tu peux remplacer le -exec
par un xargs (avec l'option -0 bien sur et un print0 dans le find)


find -print0 n'est pas posix, pas plus que xargs -0

Ce sont des extensions GNU.

--
JR


Avatar
Nicolas George
Benoit Izac wrote in message :
- ça ne fonctionnera pas si tu n'es pas propriétaire de $D (cas de
$D avec le sticky bit).


Petite erreur ici : le sticky-bit joue s'il est sur le parent de $D, pas sur
$D lui-même.

Avatar
Benoit Izac
Bonjour,

le 10/03/2007 à 18:07, Nicolas George a écrit dans le message
<45f2e5e8$0$3217$ :

- ça ne fonctionnera pas si tu n'es pas propriétaire de $D (cas de
$D avec le sticky bit).


Petite erreur ici : le sticky-bit joue s'il est sur le parent de $D,
pas sur $D lui-même.


Le sticky bit joue sur ses descendants. J'ai parlé du sticky bit en
pensant à « /tmp » mais en fait ça n'a rien à voir dans mon cas.

J'aurais du dire :
- ça ne fonctionne pas si tu n'as pas la permission en écriture sur
le parent de $D, rm va échoué.

--
Benoit Izac


Avatar
Stephane Chazelas
2007-03-10, 17:09(+01), Benoit Izac:
Bonjour,

Je cherche à vider le répertoire $D de tout ce qu'il contient. Je
considère que le propriétaire de son contenu (pas forcément du
répertoire lui-même) est le même que celui qui lance la commande. Je ne
souhaite utiliser que des commandes POSIX.

Je ne vois qu'une solution :
% (cd $D && find . ! -name . -prune -exec rm -fr -- {} +)

Fonctionne-t-elle dans tous les cas ?
[...]


(unset CDPATH
cd -P -- "$D" &&
find . ! -name . -prune -exec rm -fr {} +)

ou

find "$D/." ! -name . -prune -exec rm -rf {} +
(dans la mesure ou $D ne commence pas part "-")


Tu as aussi:

ln -s "$D" "$D.link" &&
rm -rf "$D.link/"

(dans la mesure ou "$D" est absolu).

qui est POSIX (je pense) mais ne marche pas avec GNU rm sous
Linux (entre autres).

--
Stéphane

Avatar
Benoit Izac
Bonjour,

le 10/03/2007 à 19:09, Stephane Chazelas a écrit dans le message
:

Je cherche à vider le répertoire $D de tout ce qu'il contient. Je
considère que le propriétaire de son contenu (pas forcément du
répertoire lui-même) est le même que celui qui lance la commande. Je
ne souhaite utiliser que des commandes POSIX.
[...]



ln -s "$D" "$D.link" &&
rm -rf "$D.link/"

(dans la mesure ou "$D" est absolu).

qui est POSIX (je pense) mais ne marche pas avec GNU rm sous
Linux (entre autres).


Tu es sûr ? Ça me parait plutôt dangereux comme commande. Un « / » en
trop en voulant supprimer un lien symbolique et on perd le contenu du
répertoire (et le lien).

Selon SUSv3 pour rm(1) (je ne suis pas sûr de bien comprendre la
dernière phrase) :

| The rm utility removes symbolic links themselves, not the files they
| refer to, as a consequence of the dependence on the unlink()
| functionality, per the DESCRIPTION. When removing hierarchies with -r
| or -R, the prohibition on following symbolic links has to be made
| explicit.

Mais la description de unlink(2) me paraît claire :

| The unlink() function shall remove a link to a file. If path names
| a symbolic link, unlink() shall remove the symbolic link named by path
| and shall not affect any file or directory named by the contents of
| the symbolic link.

--
Benoit Izac


Avatar
Nicolas George
Benoit Izac wrote in message :
Tu es sûr ? Ça me parait plutôt dangereux comme commande. Un « / » en
trop en voulant supprimer un lien symbolique et on perd le contenu du
répertoire (et le lien).


C'est surtout le -r qui est en trop, dans ce cas.

Avatar
Stephane Chazelas
2007-03-10, 22:58(+01), Benoit Izac:
Bonjour,

le 10/03/2007 à 19:09, Stephane Chazelas a écrit dans le message
:

Je cherche à vider le répertoire $D de tout ce qu'il contient. Je
considère que le propriétaire de son contenu (pas forcément du
répertoire lui-même) est le même que celui qui lance la commande. Je
ne souhaite utiliser que des commandes POSIX.
[...]



ln -s "$D" "$D.link" &&
rm -rf "$D.link/"

(dans la mesure ou "$D" est absolu).

qui est POSIX (je pense) mais ne marche pas avec GNU rm sous
Linux (entre autres).


Tu es sûr ? Ça me parait plutôt dangereux comme commande. Un « / » en
trop en voulant supprimer un lien symbolique et on perd le contenu du
répertoire (et le lien).

Selon SUSv3 pour rm(1) (je ne suis pas sûr de bien comprendre la
dernière phrase) :

| The rm utility removes symbolic links themselves, not the files they
| refer to, as a consequence of the dependence on the unlink()
| functionality, per the DESCRIPTION. When removing hierarchies with -r
| or -R, the prohibition on following symbolic links has to be made
| explicit.

Mais la description de unlink(2) me paraît claire :

| The unlink() function shall remove a link to a file. If path names
| a symbolic link, unlink() shall remove the symbolic link named by path
| and shall not affect any file or directory named by the contents of
| the symbolic link.


Oui mais $D.link/ n'est pas un lien symbolique, c'est censé etre
la meme chose que $D.link/. d'apres POSIX.

Tu verras qu'un lstat renvoir S_IFDIR dessus:

$ strace -e lstat64 ls -ld 1 1.link 1.link/
lstat64("1", {st_mode=S_IFDIR|0755, st_sizee536, ...}) = 0
lstat64("1.link", {st_mode=S_IFLNK|0777, st_size=1, ...}) = 0
lstat64("1.link/", {st_mode=S_IFDIR|0755, st_sizee536, ...}) = 0

Cela dit, sous Linux (2.6.19), les rm et unlink ne semblent pas
faire ce qu'il faut.

$ strace rm -rf 1.link/
[...]
unlink("1.link/") = -1 ENOTDIR (Not a directory)
[...]

???

J'imagine que c'est plutot linux qui est a blamer ici. rm
probablement fait la descente recursive si unlink renvoie un
EISDIR.

--
Stéphane



Avatar
Benoit Izac
Bonjour,

le 11/03/2007 à 15:14, Stephane Chazelas a écrit dans le message
:

ln -s "$D" "$D.link" &&
rm -rf "$D.link/"




J'ai fait quelques tests avec ce que j'avais sous la main :
- Linux : ne supprime rien
- OpenBSD : supprime $D.link uniquement
- FreeBSD : supprime $D et son contenu mais pas $D.link

Je vais garder ma solution à base de find. ;-)

--
Benoit Izac



1 2