vider un répertoire

Le
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
Vidéos High-Tech et Jeu Vidéo
Téléchargements
Vos réponses Page 1 / 2
Gagnez chaque mois un abonnement Premium avec GNT : Inscrivez-vous !
Trier par : date / pertinence
ALain Montfranc
Le #729869
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 ?

Benoit Izac
Le #729868
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


Jean-Rene David
Le #729867
* 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


Nicolas George
Le #729866
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.

Benoit Izac
Le #729865
Bonjour,

le 10/03/2007 à 18:07, Nicolas George a écrit dans le 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.


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


Stephane Chazelas
Le #729864
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

Benoit Izac
Le #729863
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


Nicolas George
Le #729862
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.

Stephane Chazelas
Le #729592
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



Benoit Izac
Le #729587
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



Publicité
Poster une réponse
Anonyme