¿Cómo eliminar este directorio indeleble?

40

Desmarqué un archivo tar corrupto y logré terminar con un directorio que no puedo eliminar. Si trato de eliminarlo, parece que no se puede encontrar, pero lsmuestra que está presente, tanto con bash como con python. comportamiento similar, excepto justo después de que trato de eliminarlo rm -rf, se lsqueja de que no puede encontrarlo, luego lo enumera (ver más abajo después rm -rf). El findcomando muestra que el archivo está presente, pero aún no se me ocurre una forma de eliminarlo.
Aquí están mis intentos:

Aquí ves ambos lsy findaceptas que tenemos un directorio,

rl]$ ls
mikeaâ??cnt
rl]$ find -maxdepth 1 -type d -empty -print0  
./mikeaâcnt 

Pero no puedo eliminarlo:

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

Sin cdembargo, puedo hacerlo y está vacío:

rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ pwd
.../rl/mikeaâcnt


mikeaâ^Á^Äcnt]$ cd ../
rl]$ ls
mikeaâ??cnt

vea a continuación que no es un archivo simple sino un directorio, además se lscomporta de manera divertida después de rm -rf que dice que no puede encontrar el archivo y luego lo enumera inmediatamente despué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]$ 

Entonces este es el intento con python, se encuentra el archivo, pero el nombre no se puede usar como un nombre que se puede eliminar:

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'

incluso cuando uso la finalización de pestañas, el nombre que recoge no se puede usar:

rl]$ rm -rf mikeaâ^Á^Äcnt 
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

usando el nombre que Python muestra con bash obtengo esto:

rl]$ rm -rf "mikea\xc3\xa2\xc2\x81\xc2\x84cnt"
rl]$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

¿Hay algo que pueda hacer para deshacerme de este directorio corrupto? El sistema de archivos subyacente (NFS) parece funcional y no se informan otros problemas, y no he tenido tales problemas hasta el archivo tar corrupto.

EDITAR: Aquí está usando findla propia -execopción para llamarrm

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]$

pero el archivo todavía está allí (se lsqueja de que no puede encontrarlo, pero luego lo muestra de todos modos)

2da EDICIÓN:

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

El comportamiento sigue sin cambios, el archivo sigue presente

3a EDICIÓN:

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

Parece que hay más en el nombre que mikeaâcntmirar la salida del intento de Python mikea\xc3\xa2\xc2\x81\xc2\x84cnt, y esta captura de pantalla:

salida ls

4th EDIT: este es el intento con un comodín:

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

y mi localidad:

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=

5ta Edición:

rl]$ ls -i 
ls: cannot access mikeaâcnt: No such file or directory
? mikeaâ??cnt

pero también el comportamiento ha cambiado, ahora lsy cd haz esto:

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.

Esto ha sucedido después de los intentos de eliminación, estoy pensando que podrían ser problemas de NFS como se sugiere en una de las respuestas aquí por vinc17.

6ª EDICIÓN: Esta es la salida lsofyls -a

rl] $ / usr / sbin / lsof mikeaâ ^ Á ^ Äcnt lsof: error de estado en mikeaâ \ xc2 \ x81 \ xc2 \ x84cnt: No existe tal archivo o directorio

arriba está mal, aquí está la lsofinvocación correcta : (rl es el directorio padre)

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ª Edición: movimiento no va a funcionar, (I probado antes de todo esto, pero no lo hice guardar la salida), pero tiene el mismo problema que lsy rm con el archivo.

8ª EDICIÓN: esto está usando los caracteres hexadecimales como se sugiere:

 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]$

Novena edición: para el statcomando:

 rl]$ stat  mikeaâ^Á^Äcnt 
stat: cannot stat `mikeaâ\302\201\302\204cnt': No such file or directory
 rl]$

Parece aún más probable de todos los resultados, hay un error u otro mal comportamiento de NFS como se sugiere en los comentarios.

Edición 10: Esta es una salida extraña en una esencia ya que es tan grande, es la salida o estos dos comandos:

strace -xx rmdir ./* | grep -e '-1 E'`
strace -xx -e trace=file ls -li`

https://gist.github.com/mikeatm/e07fa600747a4285e460

Edición 11: Entonces, antes de lo anterior rmdir, noté que podía cdingresar al directorio, pero después de rmdireso no pude cdnuevamente, similar a ayer. Los archivos .y ..estaban presentes:

rl]$ ls
mikeaâ??cnt
rl]$ cd mikeaâ^Á^Äcnt/
mikeaâ^Á^Äcnt]$ ls
mikeaâ^Á^Äcnt]$ ls  -a
.  ..
mikeaâ^Á^Äcnt]$ cd ../

Edición final: vi a un administrador local sobre esto y se solucionó iniciando sesión en el servidor y eliminando desde allí. La explicación de ellos es que podría ser un problema que los conjuntos de caracteres en el nombre sean inapropiados.

mike-m
fuente
¿Hay alguna razón por la que está canalizando findla salida a un comando diferente en lugar de solo usar su execopción?
HalosGhost
@HalosGhost no había razón, vea la edición para obtener información adicional sobre su pregunta
mike-m
2
Como alguien con muy poca experiencia con Unix y Linux, esta es mi idea: intente cambiar el nombre del directorio a algo sin usar esos símbolos mv. tal vez puedas borrarlo después de eso. Alternativamente, puede intentar mover el directorio a un nivel de carpeta más profundo (tal vez con un comodín) y luego eliminar la carpeta a la que lo ha movido.
Nzall
44
Sospecho que el directorio solo existe en la memoria del cliente y hace mucho que desapareció en el servidor. ¿Has intentado desmontarlo y volver a montarlo? ¿Has intentado reiniciar el cliente? ¿Es visible en otros clientes?
kasperd
66
@ mike-m Parece que has encontrado un error NFS, probablemente en el servidor NFS. O eso o corrupción del sistema de archivos en el servidor. Dudo que realmente pueda hacer otra cosa que no sea esperar a que los administradores del servidor NFS se encarguen de ello.
derobert

Respuestas:

11

El siguiente extracto de este ensayo explica potencialmente por qué ese directorio se niega a ser eliminado:

NFSv4 requiere que todos los nombres de archivo se intercambien utilizando UTF-8 a través del cable. La especificación NFSv4, RFC 3530, dice que los nombres de archivo deben estar codificados en UTF-8 en la sección 1.4.3: "En una ligera desviación, los nombres de archivo y directorio están codificados con UTF-8 para tratar los conceptos básicos de la internacionalización". El mismo texto también se encuentra en la nueva sección NFS 4.1 RFC (RFC 5661) 1.7.3. El cliente actual de Linux NFS simplemente pasa los nombres de archivo directamente, sin ninguna conversión de la configuración regional actual hacia y desde UTF-8. El uso de nombres de archivo que no sean UTF-8 podría ser un problema real en un sistema que usa un sistema NFSv4 remoto; se supone que cualquier servidor NFS que siga la especificación NFS rechazará nombres de archivos que no sean UTF-8. Por lo tanto, si desea asegurarse de que sus archivos se puedan almacenar realmente desde un cliente Linux a un servidor NFS, actualmente debe usar nombres de archivo UTF-8. En otras palabras,

UTF-8 es un enfoque a más largo plazo. Los sistemas deben admitir UTF-8, así como las codificaciones más antiguas, lo que les da tiempo a las personas para cambiar a UTF-8. Para utilizar "UTF-8 en todas partes", todas las herramientas deben actualizarse para admitir UTF-8. Hace años, este era un gran problema, pero a partir de 2011 se trata esencialmente de un problema resuelto, y creo que la trayectoria es muy clara para esos pocos sistemas finales.

No todas las secuencias de bytes son legales UTF-8, y no desea tener que descubrir cómo mostrarlas. Si el núcleo aplica estas restricciones, asegurando que solo se permitan los nombres de archivo UTF-8, entonces no hay problema ... todos los nombres de archivo serán legales UTF-8. La función utf8_check C de Markus Kuhn puede determinar rápidamente si una secuencia es válida UTF-8.

El sistema de archivos debería exigir que los nombres de archivo cumplan con algún estándar, no debido a alguna necesidad malvada de controlar a las personas, sino simplemente para que los nombres siempre se puedan mostrar correctamente en un momento posterior. La falta de estándares hace las cosas más difíciles para los usuarios, no más fáciles. Sin embargo, el sistema de archivos no obliga a los nombres de archivo a ser UTF-8, por lo que puede tener basura fácilmente.

Timothy Martin
fuente
Esto parece hacer eco de la explicación de los administradores locales, lo marcaré como la respuesta de la explicación de los administradores. Ver mi edición final
mike-m
19

Una forma de eliminar archivos / directorios como este es mediante su referencia de inodo.

Para encontrar los inodes para elementos en el directorio actual:

ls -i
14813568 mikeaâcnt

Para borrar esto:

find . -inum 14813568 -delete
Nicolai
fuente
por favor vea la 5ta edición.
mike-m
44
No, esto no elimina archivos por su inodo. Esto busca un nombre de archivo para el inodo dado y luego elimina el archivo por su nombre. No puede ayudar aquí, ya que se hizo un intento con el nombre correcto (junto con otros intentos con un nombre incorrecto).
Gilles 'SO- deja de ser malvado'
@Gilles: técnicamente, busca una negación de inodo y devuelve un nombre de archivo, pero estoy de acuerdo.
mikeserv
1
@Nicolai no me ayuda. Aparece un mensaje de directorio no vacío.
difractada el
1
Sí, ja, historia divertida sobre esto: el archivo que estoy tratando de eliminar tiene ?como referencia de inodo. ¿Cómo lo eliminas entonces?
Financia la demanda de Mónica el
7

No debe usar caracteres que no sean ASCII en la línea de comando ya que, como puede ver, por alguna razón, no necesariamente se corresponden con el nombre del archivo (Unicode tiene varias formas de expresar letras acentuadas). Algo como:

rm -rf mike*

debería funcionar ya que el nombre de archivo es generado directamente por el shell. Pero asegúrese de que solo haya una coincidencia (haga una echo mike*primera para confirmar).

Bueno, si cdfunciona, entonces no hay razón por la cual rm, o lsdebería decir No such file or directory, por lo que el problema puede estar en el nivel del sistema de archivos.

Nota: No utilice lspara buscar si un directorio está vacío, pero ls -a.

El directorio aún puede ser utilizado por otro proceso (incluso si es el cwd de algún proceso). En mi humilde opinión, es por eso que todavía "existe" pero puede producir errores, por ejemplo, con ls; lsofpuede darle alguna información, pero con NFS, necesita encontrar qué máquina la usa. Especialmente con NFS, esto puede producir errores extraños. ls -aen el directorio principal podría mostrarle .nfs*archivos / directorios en algunos casos.

Cuando tengas:

$ ls
ls: cannot access mikeaâcnt: No such file or directory
mikeaâ??cnt

Sospecho que el archivo todavía existe en la tabla de directorio debido al almacenamiento en caché de NFS y / o porque es utilizado por otro proceso, pero sin la información asociada. Cuando lsintenta obtener información sobre el archivo en sí, recibe un error ya que el archivo en sí ya no existe (solo está en la tabla del directorio), de ahí el error que se muestra. Luego lsgenera el nombre del archivo porque está en la tabla de directorio. El hecho de que tenga signos de interrogación en un caso, pero no en el otro, se debe a un error de visualización en lsmi humilde opinión (no relacionado con su problema).

vinc17
fuente
Había probado un comodín antes, no funcionó, y no pude publicar ese intento en mi pregunta, actualizaré con el resultado
mike-m
Ver mi tercera edición. En mi humilde opinión esto se debe a NFS (probablemente no corrupción, pero mal almacenamiento en caché) y posiblemente el hecho de que otro proceso está utilizando el directorio. En algunos casos, uno necesita reiniciar todo (el servidor y los clientes).
vinc17
Tal vez esto podría explicar las cosas, pero no puedo estar seguro, ya que no tengo los privilegios para retirarlo para las pruebas. Ver la 5ta edición.
mike-m
1
@ vinc17 Por favor, no use "EDITAR" en su respuesta, porque para el nuevo lector no tiene sentido (ya hay un historial de edición)
Bernhard
iv añadido alguna salida lsof, sin saber si se le puede decir nada aunque,
Mike-m
3

He probado personalmente usando findla -execdirectiva de:

$ mkdir -p mikeaâcnt
$ ls
mikeaâcnt
$ find -maxdepth 1 -type d -empty -exec rm -rf {} +
$ ls
$ 

La carpeta se creó y eliminó correctamente.

Como señaló @Igeorget , hay un método aún más simple si tienes GNU find:

$ find -maxdepth 1 -type d -empty -delete

También probé este comando y funciona correctamente

HalosGhost
fuente
Y si usa el hallazgo de GNU, también hay una -deleteopción.
lgeorget
Por favor, vea la tercera edición,
mike-m
1

He tenido el mismo problema, creo. He visto el problema anteriormente con un nombre de archivo de . lsen este caso mostraba el archivo como â??, pero pude eliminarlo con rm ☃.

Esto me llevó a la siguiente forma de convertir el nombre incorrecto al correcto:

Primero obtenga los bytes del nombre de archivo:

$ ls --show-control-chars | xxd
0000000: 6d69 6b65 61c3 a2c2 81c2 8463 6e74 0a    mikea......cnt.

Luego decodifique estos bytes como UTF-8, para obtener los puntos de código unicode, utilizando la entrada hexadecimal de este sitio web, por ejemplo: 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 (&#x00E2;)
U+0081 <control> character (&#x0081;)
U+0084 <control> character (&#x0084;)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character

Observe que todos estos están debajo del límite de bytes. Obtenemos los siguientes bytes:

6D 69 6B 65 61 E2 81 84 63 6E 74

Si tratamos esta secuencia en UTF-8 obtenemos:

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 (&#x2044;)
U+0063 LATIN SMALL LETTER C character
U+006E LATIN SMALL LETTER N character
U+0074 LATIN SMALL LETTER T character

Y, por lo tanto, su nombre de archivo es:, mikea⁄cntcon una barra diagonal en lugar de una normal hacia adelante. Ahora puede pasar este nombre a rmdir.

mvdnes
fuente
Eso es ingenioso, si me encuentro con esto de nuevo, lo tendré en cuenta. bueno +1
mike-m
0

Después de obtener el código hexadecimal correcto del nombre de archivo / carpeta (usando el método que uno considere apropiado, puedo elegir ls --show-control-chars | xxd), se debe usar una construcción especial para abordar dichos caracteres cuando se ejecuta bajo bash:

rmdir $'mikea\xc3\xa2\xc2\x81\xc2\x84cnt'

De lo contrario, las barras invertidas se tratan como barras invertidas de vainilla.

Abel Cheung
fuente
Por favor, eche un vistazo a mi edición (8a edición)
mike-m
@ mike-m Por supuesto que no existe, porque lsincluye nueva línea en los datos de salida y el "cnt" está duplicado. ¿Quizás pueda intentar copiar y pegar directamente la línea en mi respuesta y ver si es efectiva?
Abel Cheung
No, aún así: `` `rl] $ rmdir $ 'mikea \ xc3 \ xa2 \ xc2 \ x81 \ xc2 \ x84cnt' rmdir: no se pudo eliminar` mikeaâ \ 302 \ 201 \ 302 \ 204cnt ': no ​​existe tal archivo o directorio `` `
mike-m
En ese caso, es muy probable que sea una combinación del problema de NFS y la configuración regional que impide que la mayoría de las utilidades del sistema pasen bytes incorrectos que no sean UTF8. Y parece que la eliminación del inodo ha empeorado la situación. Por ahora, la única manera que se me ocurre es el establecimiento de su sistema a un ambiente libre de configuración regional (uso "C" configuración regional para LC_*y LANGlas variables env), y montar NFS sin ninguna opción de conjunto de caracteres
Abel Cheung
0

¿Has intentado usar rm -rf ./mikeaâcnto rm -rf "./mikeaâcnt"o una ruta absoluta? También en lugar de rmintentarlo rmdir ./mikeaâcnt.

walsht
fuente
parte del problema es que los caracteres mikeaâcntno parecen ser el nombre del archivo, sino lo que se ls muestra, vea la tercera edición
mike-m
0

¿Has intentado obtener el inodo de ese archivo con stat:

stat mike*

Eso debería darle el número de inodo (y otros datos), y luego podría intentar eliminarlo.

rsuarez
fuente
iv agregó una edición con statbehavour,
mike-m
0

Tuve problemas similares. ¿Tienes Gnome, KDE o algún tipo de Xwindow DM ?. Si abre el archivo broser y elimina el archivo de allí.

Deberia de funcionar.

Me gustaría ver una solución desde la línea de comandos, pero en mi caso y después de perder mucho tiempo tratando de descubrir cómo eliminarla de la línea de comando, descubrí que era tan simple como eliminar cualquier otro archivo de nautilus o cualquier otro explorador de archivos (la verdad es que solo lo he intentado con nautilus).

YoMismo
fuente