J'ai décompressé un fichier tar corrompu et j'ai réussi à me retrouver avec un répertoire que je ne peux pas supprimer. Si j'essaie de le supprimer, il semble qu'il ne peut pas être trouvé, mais ls
montre qu'il est présent, à la fois avec bash et avec python j'obtiens un comportement similaire, sauf juste après avoir essayé de le supprimer avec rm -rf
, ls
se plaint de ne pas le trouver, puis il le répertorie (voir ci-dessous après rm -rf
). La commande find
montre que le fichier est présent, mais je ne trouve toujours pas de moyen de le supprimer.
Voici mes tentatives:
Ici, vous voyez à la fois ls
et find
convenir que nous avons un répertoire,
rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -print0
./mikeaâcnt
Mais je ne peux pas le supprimer:
rl]$ find -maxdepth 1 -type d -empty -print0 | xargs -0 rm -f -v
rm: cannot remove `./mikeaâ\302\201\302\204cnt': Is a directory
rl]$ ls
mikeaâ??cnt
Je peux cd
et c'est vide:
rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ pwd
.../rl/mikeaâcnt
mikeaâ^Á^Äcnt]$ cd ../
rl]$ ls
mikeaâ??cnt
voir ci-dessous qui n'est pas un simple fichier mais un répertoire, plus ls
se comporte de façon amusante après le rm -rf
il indique qu'il ne trouve pas le fichier, puis le répertorie juste après:
rl]$ rm mikeaâ^Á^Äcnt/
rm: cannot remove `mikeaâ\302\201\302\204cnt/': Is a directory
rl]$ rm -rf mikeaâ^Á^Äcnt/
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$
C'est donc la tentative avec python, le fichier est trouvé, mais le nom n'est pas utilisable comme nom qui peut être supprimé:
rl]$ python
Python 2.6.6 (r266:84292, Jul 10 2013, 22:48:45)
[GCC 4.4.7 20120313 (Red Hat 4.4.7-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> import shutil
>>> os.listdir('.')
['mikea\xc3\xa2\xc2\x81\xc2\x84cnt']
>>> shutil.rmtree(os.listdir('.')[0] )
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib64/python2.6/shutil.py", line 204, in rmtree
onerror(os.listdir, path, sys.exc_info())
File "/usr/lib64/python2.6/shutil.py", line 202, in rmtree
names = os.listdir(path)
OSError: [Errno 2] No such file or directory: 'mikea\xc3\xa2\xc2\x81\xc2\x84cnt'
même lorsque j'utilise la complétion de tabulation, le nom qu'il prend n'est pas utilisable:
rl]$ rm -rf mikeaâ^Á^Äcnt
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
en utilisant le nom que python montre avec bash j'obtiens ceci:
rl]$ rm -rf "mikea\xc3\xa2\xc2\x81\xc2\x84cnt"
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Puis-je faire quelque chose pour me débarrasser de ce répertoire corrompu? Le système de fichiers sous-jacent (NFS) semble fonctionnel et aucun autre problème n'est signalé, et je n'ai pas eu de tels problèmes jusqu'à ce que le fichier tar corrompu.
EDIT: Voici l'utilisation de find
propre -exec
option pour appeler rm
rl]$ find -maxdepth 1 -type d -empty -exec rm -f {} \;
find: `./mikeaâ\302\201\302\204cnt': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$
mais le fichier est toujours là (ls
se plaint qu'il ne le trouve pas, mais l'affiche quand même)
2e EDIT:
rl]$ find -maxdepth 1 -type d -empty -exec rm -rf {} \;
find: `./mikeaâ\302\201\302\204cnt': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Le comportement est toujours inchangé, le fichier est toujours présent
3ème EDIT:
rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -exec rm -rf {} +
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Il semble y avoir plus de nom que mikeaâcnt
en regardant la sortie de la tentative python mikea\xc3\xa2\xc2\x81\xc2\x84cnt
, et cette capture d'écran:
4ème EDIT: C'est la tentative avec un joker:
rl]$ echo *
mikeaâcnt
rl]$ echo mike*
mikeaâcnt
rl]$ rm -rf mike*
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
et mes paramètres régionaux:
rl]$ locale
LANG=en_US.utf8
LC_CTYPE="en_US.utf8"
LC_NUMERIC="en_US.utf8"
LC_TIME="en_US.utf8"
LC_COLLATE="en_US.utf8"
LC_MONETARY="en_US.utf8"
LC_MESSAGES="en_US.utf8"
LC_PAPER="en_US.utf8"
LC_NAME="en_US.utf8"
LC_ADDRESS="en_US.utf8"
LC_TELEPHONE="en_US.utf8"
LC_MEASUREMENT="en_US.utf8"
LC_IDENTIFICATION="en_US.utf8"
LC_ALL=
5e édition:
rl]$ ls -i
ls: cannot access mikeaâcnt: No such file or directory
? mikeaâ??cnt
mais aussi le comportement a changé, maintenant ls
et cd
font ceci:
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt
mikeaâcnt: No such file or directory.
Cela s'est produit après les tentatives de suppression, je pense que ce pourrait être des problèmes NFS comme suggéré dans l'une des réponses ici par vinc17.
6ème EDIT: c'est la sortie de lsof
et ls -a
rl] $/usr/sbin/lsof mikeaâ ^ Á ^ Äcnt lsof: erreur d'état sur mikeaâ\xc2\x81\xc2\x84cnt: aucun fichier ou répertoire de ce type
ci-dessus est faux, voici l'invocation correcte de lsof
: (rl est le répertoire parent)
rl]$ /usr/sbin/lsof | grep mike | grep rl
tcsh 11926 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
lsof 14733 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
grep 14734 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
grep 14735 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
lsof 14736 mike cwd DIR 0,33 4096 19569249 /home/mike/mish/rl
rl]$
rl]$ ls -a
ls: cannot access mikeaâcnt: No such file or directory
. .. mikeaâ??cnt
7ème édition: déplacer ne fonctionnera pas, (je l'ai essayé avant tout cela, mais je n'ai pas enregistré la sortie), mais il a le même problème que ls
et rm
avec le fichier.
8ème EDIT: ceci utilise les caractères hexadécimaux comme suggéré:
rl]$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a mikea......cnt.
rl]$ rmdir $'mikea\6d69\6b65\61c3\a2c2\81c2\8463\6e74\0acnt'
rmdir: failed to remove `mikea\006d69\006b651c3\a2c2\\81c2\\8463\006e74': No such file or directory
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
rl]$
9ème édition: pour la commande stat
:
rl]$ stat mikeaâ^Á^Äcnt
stat: cannot stat `mikeaâ\302\201\302\204cnt': No such file or directory
rl]$
Cela semble encore plus probable à partir de toutes les sorties, il y a un bug ou un autre mauvais comportement NFS comme suggéré dans les commentaires.
Edit 10: Il s'agit de la sortie strace dans un Gist car c'est si grand, c'est la sortie ou ces deux commandes:
strace -xx rmdir ./* | grep -e '-1 E'`
strace -xx -e trace=file ls -li`
https://Gist.github.com/mikeatm/e07fa600747a4285e46
Edit 11: Donc, avant le rmdir
ci-dessus, j'ai remarqué que je pouvais cd
dans le répertoire, mais après le rmdir
je ne pouvais plus cd
, semblable à hier. Le .
et ..
des fichiers étaient présents:
rl]$ ls
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ ls -a
. ..
mikeaâ^Á^Äcnt]$ cd ../
Édition finale: j'ai vu un administrateur local à ce sujet et cela a été résolu en se connectant au serveur lui-même et en le supprimant. Leur explication est que cela pourrait être un problème avec des jeux de caractères dans le nom inappropriés.
L'extrait suivant de cet essai explique potentiellement pourquoi ce répertoire refuse d'être supprimé:
NFSv4 nécessite que tous les noms de fichiers soient échangés en utilisant UTF-8 sur le câble. La spécification NFSv4, RFC 3530, stipule que les noms de fichiers doivent être encodés en UTF-8 dans la section 1.4.3: "Dans un léger départ, les noms de fichiers et de répertoires sont encodés en UTF-8 pour gérer les bases de l'internationalisation." Le même texte se trouve également dans la nouvelle section NFS 4.1 RFC (RFC 5661) 1.7.3. Le client Linux NFS actuel transmet simplement les noms de fichiers directement, sans aucune conversion des paramètres régionaux actuels vers et depuis UTF-8. L'utilisation de noms de fichiers non UTF-8 pourrait être un réel problème sur un système utilisant un système NFSv4 distant; tout serveur NFS qui suit la spécification NFS est censé rejeter les noms de fichiers non UTF-8. Donc, si vous voulez vous assurer que vos fichiers peuvent réellement être stockés d'un client Linux vers un serveur NFS, vous devez actuellement utiliser les noms de fichiers UTF-8. En d'autres termes, bien que certaines personnes pensent que Linux ne force pas le codage d'un caractère particulier sur les noms de fichiers, dans la pratique, il nécessite déjà un codage UTF-8 pour les noms de fichiers dans certains cas.
UTF-8 est une approche à plus long terme. Les systèmes doivent prendre en charge l'UTF-8 ainsi que les nombreux encodages plus anciens, ce qui donne aux utilisateurs le temps de passer à l'UTF-8. Pour utiliser "UTF-8 partout", tous les outils doivent être mis à jour pour prendre en charge UTF-8. Il y a des années, c'était un gros problème, mais à partir de 2011, c'est essentiellement un problème résolu, et je pense que la trajectoire est très claire pour ces quelques systèmes traînants.
Toutes les séquences d'octets ne sont pas des formats UTF-8 légaux, et vous ne voulez pas avoir à comprendre comment les afficher. Si le noyau applique ces restrictions, garantissant que seuls les noms de fichiers UTF-8 sont autorisés, alors il n'y a aucun problème ... tous les noms de fichiers seront légaux UTF-8. La fonction utf8_check C de Markus Kuhn peut rapidement déterminer si une séquence est UTF-8 valide.
Le système de fichiers devrait exiger que les noms de fichiers répondent à certaines normes, non pas à cause d'un besoin maléfique de contrôler les gens, mais simplement pour que les noms puissent toujours être affichés correctement ultérieurement. L'absence de normes rend les choses plus difficiles pour les utilisateurs, pas plus faciles. Pourtant, le système de fichiers ne force pas les noms de fichiers à être UTF-8, il peut donc facilement avoir des ordures.
Une façon de supprimer des fichiers/répertoires comme celui-ci est par leur référence d'inode.
Pour trouver les inodes des éléments dans le répertoire courant:
ls -i
14813568 mikeaâcnt
Pour supprimer ceci:
find . -inum 14813568 -delete
Vous ne devez pas utiliser de caractères non ASCII dans la ligne de commande car, comme vous pouvez le voir, pour une raison quelconque, ils ne correspondent pas nécessairement au nom de fichier (Unicode a différentes manières d'exprimer des lettres accentuées). Quelque chose comme:
rm -rf mike*
devrait fonctionner puisque le nom de fichier est directement généré par le Shell. Mais assurez-vous qu'il n'y a qu'une seule correspondance (faites un echo mike*
premier à confirmer).
Eh bien, si cd
fonctionne, il n'y a aucune raison pour que rm
ou ls
devrait dire No such file or directory
, afin que le problème soit au niveau du système de fichiers.
Remarque: n'utilisez pas ls
pour rechercher si un répertoire est vide, mais ls -a
.
Le répertoire peut toujours être utilisé par un autre processus (y compris s'il s'agit du cwd d'un processus). À mon humble avis, c'est pourquoi il "existe" toujours mais peut générer des erreurs, par exemple avec ls
; lsof
peut vous donner quelques informations, mais avec NFS, vous devez trouver quelle machine l'utilise. Surtout avec NFS, cela peut produire d'étranges erreurs. ls -a
dans le répertoire parent pourrait vous montrer .nfs*
fichiers/répertoires dans certains cas.
Quand vous obtenez:
$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt
Je soupçonne que le fichier existe toujours dans le table de répertoire en raison de la mise en cache NFS et/ou parce qu'il est utilisé par un autre processus, mais sans informations associées. Lorsque ls
essaie d'obtenir des informations sur le fichier lui-même, il obtient une erreur car le fichier lui-même n'existe plus (il se trouve uniquement dans la table des répertoires), d'où l'erreur affichée. Ensuite, ls
affiche le nom du fichier car il se trouve dans la table de répertoire. Le fait que vous ayez des points d'interrogation dans un cas mais pas dans l'autre cas est dû à un bogue d'affichage de ls
IMHO (sans rapport avec votre problème).
J'ai personnellement testé en utilisant find
-exec
directive:
$ mkdir -p mikeaâcnt
$ ls
mikeaâcnt
$ find -maxdepth 1 -type d -empty -exec rm -rf {} +
$ ls
$
Le dossier a été correctement créé et correctement supprimé.
Comme indiqué par @ Igeorget , il existe une méthode encore plus simple si vous avez GNU find
:
$ find -maxdepth 1 -type d -empty -delete
J'ai également testé cette commande, et elle fonctionne correctement
J'ai eu le même problème, je crois. J'ai vu le problème plus tôt avec un nom de fichier de ☃
. ls
dans ce cas, le fichier était affiché comme â??
, mais j'ai pu le supprimer avec rm ☃
.
Cela m'a conduit à la façon suivante de convertir le mauvais nom en un nom correct:
Obtenez d'abord les octets du nom de fichier:
$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a mikea......cnt.
Décodez ensuite ces octets en UTF-8, pour obtenir les points de code unicode, en utilisant l'entrée hexadécimale de ce site Web par exemple: http://software.hixie.ch/utilities/cgi/unicode-decoder/utf8-decoder
U+006D LATIN SMALL LETTER M character
U+0069 LATIN SMALL LETTER I character
U+006B LATIN SMALL LETTER K character
U+0065 LATIN SMALL LETTER E character
U+0061 LATIN SMALL LETTER A character
U+00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX character (â)
U+0081 <control> character ()
U+0084 <control> character („)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character
Notez que ceux-ci sont tous en dessous de la limite d'octets. Nous obtenons les octets suivants:
6D 69 6B 65 61 E2 81 84 63 6E 74
Si nous traitons cette séquence en UTF-8, nous obtenons:
U+006D LATIN SMALL LETTER M character
U+0069 LATIN SMALL LETTER I character
U+006B LATIN SMALL LETTER K character
U+0065 LATIN SMALL LETTER E character
U+0061 LATIN SMALL LETTER A character
U+2044 FRACTION SLASH character (⁄)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character
Et donc votre nom de fichier est: mikea⁄cnt
, avec une barre oblique de fraction au lieu d'une barre oblique normale. Vous pouvez maintenant transmettre ce nom à rmdir
.
Avez-vous essayé d'utiliser rm -rf ./mikeaâcnt
ou rm -rf "./mikeaâcnt"
ou un chemin absolu? Aussi, au lieu de rm
, essayez rmdir ./mikeaâcnt
.
Avez-vous essayé d'obtenir l'inode de ce fichier avec stat
:
stat mike*
Cela devrait vous donner le numéro d'inode (et d'autres données), puis vous pouvez essayer de le supprimer.
J'ai eu des problèmes similaires. Avez-vous Gnome, KDE ou une sorte de Xwindow DM?. Si vous ouvrez votre navigateur de fichiers et supprimez le fichier à partir de là.
Ça devrait marcher.
Je voudrais voir une solution à partir de la ligne de commande, mais dans mon cas et après avoir perdu beaucoup de temps à essayer de comprendre comment le supprimer de la ligne de commande, j'ai trouvé que c'était aussi simple que de supprimer tout autre fichier de nautilus ou tout autre explorateur de fichiers (la vérité est que je n'ai essayé qu'avec nautilus).
Après avoir obtenu le code hexadécimal correct du nom de fichier/dossier (en utilisant la méthode que l'on juge appropriée, je peux choisir ls --show-control-chars | xxd
), une construction spéciale devrait être utilisée pour adresser ces caractères lors de l'exécution sous bash:
rmdir $'mikea\xc3\xa2\xc2\x81\xc2\x84cnt'
Sinon, les barres obliques inverses sont traitées comme des barres obliques inverses vanille.