¿"No existe tal archivo o directorio" al intentar eliminar un archivo, pero el archivo existe?

21

Estoy tratando de eliminar una imagen png que se cargó en mi servidor a través de un script PHP. Cada vez que intento eliminarlo a través de ftp y terminal, aparece el error

No such file or directory

Sin embargo, cuando estoy lsen el directorio, el archivo aparece en la lista y también aparece en mi cliente ftp. He intentado crear un archivo con el mismo nombre y termino obteniendo dos archivos con el mismo nombre.

Puedo abrir el archivo que supuestamente no existe, pero todavía no puedo eliminarlo. También he intentado reiniciar mi servidor. ¿Alguna idea de cuál puede ser el problema? Estoy ejecutando una versión de Ubuntu de 64 bits, pero no creo que sea un problema de 32/64 bits. También debo tener en cuenta que he eliminado muchos otros archivos png cargados por el mismo script PHP.

Salida para ls -l

total 224 
-rw-r--r-- 1 www-data www-data 222838 May 13 04:14 qyxdshyikfr_fishing_timeout.png 
-rw-r--r-- 1 root root 272 May 14 06:54 upload.php

Salida al intentar rm

rm: cannot remove ‘qyxdshyikfr_fishing_timeout.png’: No such file or directory

upload.php: http://pastebin.com/z87eypTY

DevinFrancés
fuente
Copiar y pegar la salida ls -ldesde el directorio, también el pleno rmde comandos y su salida ..
heemayl
@heemayl total 224 -rw-r - r-- 1 www-data www-data 222838 13 de mayo 04:14 qyxdshyikfr_fishing_timeout.png -rw-r - r-- 1 raíz raíz 272 14 de mayo 06:54 upload.php rm: no se puede eliminar 'qyxdshyikfr_fishing_timeout.png': No existe tal archivo o directorio
DevinFrench
1
@DevinFrench edite su pregunta para agregar información.
muru
¿Desde qué directorio está ejecutando el rmcomando?
heemayl
1
@Samuel ¿Por qué sugeriría esto un problema del sistema de archivos? La unlinkllamada siempre fallará al encontrar un archivo que no existe. Cuando ejecuto ese stracecomando en mi sistema, donde sé que no tengo dicho archivo, produce una salida similar; ¡No creo que eso indique que tengo un problema con el sistema de archivos! Parece mucho más probable que el nombre del archivo sea ligeramente diferente qyxdshyikfr_fishing_timeout.pngy simplemente aparezca igual debido a las limitaciones en la forma en que se lsmuestran los nombres de los archivos, como se sugiere en otras respuestas.
Eliah Kagan

Respuestas:

21

He intentado crear un archivo con el mismo nombre y termino obteniendo dos archivos con el mismo nombre.

Eso dice, en ausencia de corrupción del sistema de archivos, que tiene dos archivos con dos nombres diferentes que parecen iguales debido a caracteres que no se imprimen o caracteres que se ven iguales en su conjunto de caracteres / fuente. La --escapeopción lses tu amigo en tales casos, como son herramientas como cat -v.

Entonces, también, es rm -i -- *

Otras lecturas

JdeBP
fuente
Yo fui el creador del archivo y el nombre del archivo que se subió. Nadie estaba tratando de sabotear mi servidor ya que soy la única persona que conoce la ruta completa para upload.php. Sin embargo, rm -i -- *funcionó.
DevinFrench
3
@DevinFrench Si esta respuesta resolvió su problema, márquela como la respuesta aceptada haciendo clic en la marca debajo del recuento de votos a favor, de modo que los futuros usuarios puedan saber que esta solución funcionó para usted.
kos
1
¿Alguien puede explicar el rm -i -- *comando?
user3731622
Por lo que entiendo: Pasar le -i indicará antes de eliminar cada archivo. --before *selecciona todos los archivos independientemente de si sus nombres incluyen caracteres especiales. Referencia: https://explainshell.com/explain?cmd=rm+-i+--+*
MoltenMuffins
16

TL; DR: Ejecutar ls -1b, buscar el nombre del archivo, copiar la línea en la que aparece y dárselo rm.

Como otros han sugerido, lo más probable es que esto se deba a limitaciones en la forma, lsy algunos otros programas, incluido el software de cliente y servidor, manejan nombres de archivo extraños, como los que contienen caracteres de control, de forma predeterminada. Su éxito con la respuesta de JdeBP sugiere fuertemente que este fue el caso, aunque hubiera sido una buena apuesta incluso antes de eso.

  • Para ls, cuando la salida estándar es un terminal, los ?caracteres se imprimen en su lugar. Entonces, si no está canalizando lsla salida de ningún otro comando (o redirigiéndolo a un registro para ver), probablemente su nombre de archivo no contenga caracteres de control. Pero hay otros caracteres problemáticos, tal vez el nombre del archivo contiene espacios en blanco al final, por ejemplo.

    Este comportamiento lspuede ser confuso pero no es un error, puede ser anulado explícitamente por el usuario (ver más abajo).

  • Al intentar acceder o eliminar un archivo de forma remota, los errores en el software del cliente o servidor pueden producir tales problemas.

    He experimentado este tipo de cosas a través de ftpmí varias veces , incluso para archivos cuyos nombres contienen espacios finales. (El hecho de que no funcionó se debió a un error en mi cliente ftp). Incluso cuando crea un archivo manualmente usted mismo, dependiendo de cómo lo esté creando, a veces es bastante fácil insertar inadvertidamente un espacio final u otro espacio en blanco que puede parecer espacios aunque no lo sea.

Esta es una situación en la que ls -1b(o dir -1) es útil:

  • -1le dice lsque muestre una entrada por línea. De esa manera no hay confusión acerca de dónde termina un nombre de archivo y comienza otro. Esto es útil para archivos con nombres raros.
  • -ble dice lsque imprima secuencias de escape para cualquier personaje especial. La salida de ls -bse puede copiar y pegar literalmente en un comando, sin comillas adicionales : todos los caracteres problemáticos ya se citan de una manera que hace que el shell los reconozca como lo que son.

Solo hay una advertencia: si el último carácter en una línea parece ser \, copie un carácter después de eso, ya que esto significa que \está citando un espacio.

Puede correr ls -1basí, o puede pasarle un patrón de globo (por ejemplo, ls -1b qyx*). Globbing puede o no encontrar el archivo, dependiendo de si los caracteres de control (u otros caracteres extraños) están presentes en la parte del nombre que aparece en el patrón global.

Después de copiar la \versión entrecomillada del nombre de archivo que le proporcionó ls, puede pegarla en un comando. No tiene que modificarlo manualmente de ninguna manera. En su caso, cuando desee eliminar el archivo, escriba rm, escriba un espacio, pegue la línea y presione Enter.

Otras lecturas:

Eliah Kagan
fuente
1
Muy guay -bthx =) y +1
AB
Algo que dejé fuera de OP fue cuando creé un archivo con el mismo nombre, en mi cliente ftp cuando intenté eliminar el primer archivo con el que estaba teniendo problemas, en su lugar eliminaría el nuevo archivo que hice. Es por eso que no pensé que hubiera personajes especiales involucrados, y todavía no sé cuál era el personaje especial desde que lo usé rm -i -- *.
DevinFrench
@DevinFrench El carácter extra es un espacio al final del nombre del archivo. Todavía está en la lssalida de la pregunta, pero solo se puede ver en modo texto cuando hace clic en "editar".
Izkata
@Izkata ¡Buena llamada! Debería haber pensado comprobar eso. También aparece cuando amplío la revisión 3 en el historial de edición (el nombre de archivo completo, incluido el espacio final, se resalta en verde y, por lo tanto, se puede discernir). Lo que has dicho es la explicación más definitiva y específicamente correcta hasta ahora: si publicaste una respuesta explicando que es de un espacio final, y cómo lo sabes, y qué comando eliminaría el archivo (si el OP todavía lo tenía) Sé que lo votaría.
Eliah Kagan
@EliahKagan Hecho, con fotos
Izkata
3
  1. Use findy verifique la salida:

    Si no se encuentra el archivo, acorte *qyxdshyikfr*ligeramente el término de búsqueda , por ejemplo: *qyxds*o *fishing*.

    sudo find . -maxdepth 1 -type f -name "*qyxdshyikfr*"
    
  2. Si está bien, use findcon el término de búsqueda en el paso 1 yrm

    find . -maxdepth 1 -type f -name "*qyxdshyikfr*" -print0 | xargs -0  rm
    
AB
fuente
1
En lugar de llamar rmpor nombre a través de una canalización de finda xargs, recomiendo simplemente usar findla -deleteacción de. Tampoco sudoes necesario. Menos significativamente, sugiero omitir, -type fexcepto cuando sea claramente útil. Presumiblemente, si la entrada que el OP desea eliminar resultó ser un enlace simbólico, por ejemplo, todavía querrían encontrarlo y aún así eliminarlo. La -deleteacción no golpeará recursivamente un directorio; tampoco lo hará su rmcomando ya que no tiene -r. Por lo tanto, no va a golpear accidentalmente una carpeta completa (no vacía) aquí al no usarla -type.
Eliah Kagan
OK, dame un segundo.
AB
En mi caso, incluso find ... -deletedice "no se puede eliminar ... No existe tal archivo o directorio"
Deja de dañar a Monica el
1

Reposicionando en detalle, ampliado de mi comentario sobre la respuesta de Eliah

El problema es invisible, pero se puede ver si sabe qué buscar: el nombre del archivo incluye un espacio al final. Debido a que copió / pegó todo el lsresultado, se puede ver en la pregunta si resalta el resultado, o edita la publicación y mueve el cursor al final, o (como señaló Eliah) mira el diferencial en el historial de edición. Destaqué el lsresultado en la publicación en esta captura de pantalla:

Espacio extra

Una pequeña sesión de terminal rápida para duplicar el problema, con comentarios:

$ touch 'foo '        # Create file with a space at the end
$ ls -l               # Space is not visible in ls output
total 0
-rw-rw-r-- 1 izkata izkata 0 May 14 21:59 foo 

$ rm foo              # Cannot remove it when not specifying the space
rm: cannot remove ‘foo’: No such file or directory

$ rm 'foo '           # Can remove it if we quote the file name and include the space
$ rm foo\             # Or can escape the space to tell bash to include it as part of the filename

El uso de la finalización de tabulación también habría evitado por completo el problema aquí, ya que bash es lo suficientemente inteligente como para escapar de los espacios correctamente (también es un buen hábito en general, acelera mucho los caminos de mecanografía) .

Por ejemplo, si hubiera escrito rm f<tab>, se habría completado automáticamente rm foo\<space><space>, como en el último ejemplo en el bloque de código anterior.

Izkata
fuente
Hago una mención especial de copiar / pegar el lsresultado porque algo similar sucedió en StackOverflow una vez (y es la razón por la que pensé en buscar esto): alguien obtuvo un carácter no imprimible en su código, y la única razón por la que alguien lo descubrió es porque ese usuario también copió / pegó en lugar de volver a escribir su código al publicar la pregunta
Izkata
0

una vez, creé un archivo para abrir Nautilus como root, pero el nombre del archivo cuando lo vi desde nautilus fue "File Browser (root)", luego cuando intenté eliminarlo como

$ rm "File Browser (Root)"
$ sudo rm "File Browser (Root)"
$ sudo rm "File Browser (Root).desktop"

la única respuesta que obtuve fue: "rm: no se puede eliminar 'File Browser (Root) .desktop': No existe tal archivo o directorio"

entonces cuando corro:

$ ls -l

Vi / recordé que el nombre del archivo, de hecho, era "Nautilus-root.desktop"

entonces corro:

$ sudo rm "Nautilus-root.desktop"

funcionó para mí, espero que ayude!

Wagner Arcieri
fuente
0

Así que tuve este problema y ninguna de estas cosas funcionó para mí. Lo que funcionó fue crear un archivo con exactamente el mismo nombre. Era una carpeta llamada Example.1.2.3, así que creé una nueva carpeta y la llamé exactamente igual a la que no se eliminaría. La carpeta anterior desapareció y eliminé la nueva.

Jamison Lifsey
fuente
0

Tuve una situación similar, después de usar rsyncpara hacer una copia de seguridad de mi directorio de imágenes en una Mac y leerlo en Ubuntu. Había dos archivos (en realidad directorios) con nombres diferentes, pero con el mismo contenido. Eliminé uno en la Papelera (usando Nautilus), pero no pude eliminar el otro, incluso desde la línea de comandos. Diría:

$ rmdir Pictures
rmdir: failed to remove 'Pictures': No such file or directory
$ rm Pictures
rm: cannot remove 'Pictures': Is a directory

Después de verificar los números de inodo con ls -i -l, resultó que ambos directorios tienen el mismo número de inodo. Parece un enlace duro ...

La solución fue sorprendentemente simple: vaciar la Papelera haciendo clic derecho en el icono. Después de eso, ambos directorios desaparecieron.

elomage
fuente