«Aucun fichier ou répertoire de ce type» lorsque vous essayez de supprimer un fichier, mais le fichier existe?

21

J'essaie de supprimer une image png qui a été téléchargée sur mon serveur via un script PHP. Chaque fois que j'essaie de le supprimer à la fois via ftp et terminal, j'obtiens l'erreur

No such file or directory

Cependant, lorsque je suis lsdans le répertoire, le fichier est répertorié et il est également répertorié dans mon client ftp. J'ai essayé de créer un fichier avec le même nom et je finis par obtenir deux fichiers avec le même nom.

Je peux ouvrir le fichier qui n'existe pas, mais je ne peux toujours pas le supprimer. J'ai également essayé de redémarrer mon serveur. Des idées quel peut être le problème? J'utilise une version 64 bits d'Ubuntu, mais je ne pense pas que ce soit un problème 32/64 bits. Je dois également noter que j'ai supprimé de nombreux autres fichiers png téléchargés par le même script PHP.

Sortie pour 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

Sortie en essayant de rm

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

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

DevinFrench
la source
Copiez collez la sortie du ls -lrépertoire, ainsi que la rmcommande complète et sa sortie ..
heemayl
@heemayl total 224 -rw-r - r-- 1 www-data www-data 222838 13 mai 04:14 qyxdshyikfr_fishing_timeout.png -rw-r - r-- 1 racine root 272 14 mai 06:54 upload.php rm: impossible de supprimer 'qyxdshyikfr_fishing_timeout.png': Aucun fichier ou répertoire de ce type
DevinFrench
1
@DevinFrench veuillez modifier votre question pour ajouter des informations.
muru
À partir de quel répertoire vous exécutez la rmcommande?
heemayl
1
@Samuel Pourquoi cela suggère-t-il un problème de système de fichiers? L' unlinkappel échouera toujours pour trouver un fichier qui n'existe pas. Lorsque j'exécute cette stracecommande sur mon système, où je sais que je n'ai pas un tel fichier, cela produit une sortie similaire; Je ne pense pas que cela indique que j'ai un problème de système de fichiers! Il semble beaucoup plus probable que le nom du fichier soit légèrement différent qyxdshyikfr_fishing_timeout.pnget apparaisse simplement le même en raison des limitations dans la façon dont lsles noms de fichiers s'affichent, comme suggéré dans d'autres réponses.
Eliah Kagan

Réponses:

21

J'ai essayé de créer un fichier avec le même nom et je finis par obtenir deux fichiers avec le même nom.

Cela signifie, en l'absence de corruption du système de fichiers, que vous avez deux fichiers avec deux noms différents qui semblent identiques en raison de caractères non imprimables ou de caractères identiques dans votre jeu de caractères / police. L' --escapeoption lsest votre ami dans de tels cas, tout comme des outils tels que cat -v.

Il en va de même pour rm -i -- *

Lectures complémentaires

JdeBP
la source
J'étais le créateur du fichier et du nom du fichier qui a été téléchargé. Personne n'essayait de saboter mon serveur car je suis la seule personne qui connaît le chemin complet vers upload.php Cependant, a rm -i -- *fait l'affaire.
DevinFrench
3
@DevinFrench Si cette réponse a résolu votre problème, veuillez la marquer comme réponse acceptée en cliquant sur la marque sous le nombre de votes positifs, afin que les futurs utilisateurs puissent être conscients du fait que cette solution a fonctionné pour vous.
kos
1
Quelqu'un peut-il expliquer la rm -i -- *commande?
user3731622
D'après ce que je comprends: le passage -i vous invitera avant la suppression de chaque fichier. --avant *sélectionne tous les fichiers, que leurs noms incluent ou non des caractères spéciaux. Référence: https://explainshell.com/explain?cmd=rm+-i+--+*
MoltenMuffins
16

TL; DR: Exécutez ls -1b, recherchez le nom de fichier, copiez la ligne sur laquelle il apparaît et donnez-le à rm.

Comme d'autres l'ont suggéré, cela est probablement dû à des limitations dans la façon dont ls- et certains autres programmes, y compris les logiciels client et serveur - gèrent les noms de fichiers étranges, tels que ceux contenant des caractères de contrôle, par défaut. Votre succès avec la réponse de JdeBP suggère fortement que c'était le cas, même si cela aurait été un bon pari avant cela.

  • Car ls, lorsque la sortie standard est un terminal, les ?caractères sont imprimés à leur place. Donc, si vous ne lsredirigez pas la sortie vers une autre commande (ou si vous ne la redirigez pas vers un journal pour la visualisation), votre nom de fichier ne contient probablement pas de caractères de contrôle. Mais il y a d'autres caractères problématiques - peut-être que le nom du fichier contient des espaces de fin, par exemple.

    Ce comportement de lspeut être déroutant mais n'est pas un bogue, peut être explicitement remplacé par l'utilisateur (voir ci-dessous).

  • Lorsque vous tentez d'accéder ou de supprimer un fichier à distance, des bogues dans le logiciel client ou serveur peuvent produire de tels problèmes.

    J'ai vécu ce genre de choses ftpplusieurs fois par moi-même , y compris pour les fichiers dont les noms contiennent des espaces de fin. (Le fait que cela n'ait pas fonctionné était dû à un bogue dans mon client ftp.) Même lorsque vous créez manuellement un fichier vous-même, selon la façon dont vous le créez, il est parfois assez facile d'insérer par inadvertance un espace de fin ou un autre espace blanc qui peut ressembler à des espaces même si ce n'est pas le cas.

C'est une situation où ls -1b(ou dir -1) est utile:

  • -1indique lsd'afficher une entrée par ligne. De cette façon, il n'y a aucune confusion quant à la fin d'un nom de fichier et au début d'un autre. C'est pratique pour les fichiers aux noms étranges.
  • -bindique lsd'imprimer des séquences d'échappement pour tous les caractères spéciaux. La sortie de ls -bpeut être copiée et collée littéralement dans une commande, sans ajout de guillemets : tous les caractères problématiques sont déjà cités de manière à ce que le shell les reconnaisse tels qu'ils sont.

Il n'y a qu'une seule mise en garde: si le dernier caractère sur une ligne semble être \, copiez un caractère après cela, car cela signifie \citer un espace.

Vous pouvez exécuter ls -1bjuste comme ça, ou vous pouvez lui passer un modèle de glob de shell (par exemple, ls -1b qyx*). Globbing peut ou non trouver le fichier, selon que les caractères de contrôle (ou d'autres caractères étranges) sont présents ou non dans la partie du nom apparaissant dans le modèle global.

Après avoir copié la \version citée du nom de fichier qui vous a été donné par ls, vous pouvez le coller dans une commande. Vous n'avez en aucun cas à le modifier manuellement. Dans votre cas, comme vous souhaitez supprimer le fichier, tapez rm, tapez un espace, collez la ligne et appuyez sur Enter.

Lectures complémentaires:

Eliah Kagan
la source
1
-bThx très cool =) et +1
AB
Quelque chose que j'ai omis de OP était lorsque j'ai créé un fichier avec le même nom, dans mon client ftp lorsque j'ai essayé de supprimer le premier fichier avec lequel j'avais des problèmes, il supprimerait plutôt le nouveau fichier que j'ai créé. C'est pourquoi je ne pensais pas que des caractères spéciaux étaient impliqués, et je ne sais toujours pas quel était le caractère spécial depuis que je l'ai utilisé rm -i -- *.
DevinFrench
@DevinFrench Le caractère supplémentaire est un espace à la fin du nom de fichier. Il est toujours dans la lssortie de la question, mais ne peut être vu qu'en mode texte lorsque vous cliquez sur "modifier".
Izkata
@Izkata Bon appel! J'aurais dû penser à vérifier ça. Il apparaît également lorsque je développe la révision 3 dans l'historique des modifications (le nom de fichier complet, y compris l'espace de fin, est mis en surbrillance en vert et donc perceptible). Ce que vous avez dit est l'explication la plus définitive et la plus correcte à ce jour - si vous avez publié une réponse expliquant qu'elle provient d'un espace de fin, et comment vous le savez, et quelle commande supprimerait le fichier (si l'OP l'avait toujours) , Je sais que je voterais favorablement.
Eliah Kagan
@EliahKagan Done, avec photos
Izkata
3
  1. Utilisez findet vérifiez la sortie:

    Si le fichier est introuvable, raccourcissez *qyxdshyikfr*légèrement le terme de recherche , par exemple: *qyxds*ou *fishing*.

    sudo find . -maxdepth 1 -type f -name "*qyxdshyikfr*"
    
  2. Si cela vous convient, utilisez-le findavec le terme de recherche à l'étape 1 etrm

    find . -maxdepth 1 -type f -name "*qyxdshyikfr*" -print0 | xargs -0  rm
    
UN B
la source
1
Plutôt que d'appeler rmpar son nom via un canal de findà xargs, je recommande simplement d'utiliser findl' -deleteaction de. Ce sudon'est pas non plus nécessaire. De manière moins significative, je suggère de l'omettre, -type fsauf lorsque c'est clairement utile. Vraisemblablement, si l'entrée que l'OP veut supprimer s'est avérée être un lien symbolique, par exemple, ils voudraient toujours la trouver et voudraient toujours la supprimer. L' -deleteaction n'encombrera pas récursivement un répertoire; votre rmcommande non plus puisque vous n'en avez pas -r. Donc, vous n'allez pas accidentellement détruire un dossier entier (non vide) ici en ne l'utilisant pas -type.
Eliah Kagan
OK, donnez-moi une seconde.
AB
Dans mon cas, même find ... -deletedit "ne peut pas supprimer ... Aucun fichier ou répertoire de ce type"
Stop Harming Monica
1

Republication en détail, développée à partir de mon commentaire sur la réponse d'Eliah

Le problème est invisible, mais peut être vu si vous savez quoi rechercher: Le nom du fichier comprend un espace à la fin. Étant donné que vous copiez / collez l'intégralité de la lssortie, vous pouvez voir dans la question si vous mettez en surbrillance la sortie, ou modifiez le post et déplacez le curseur à la fin, ou (comme Eliah l'a souligné) regardez le diff dans l'historique des modifications. J'ai mis en évidence la lssortie dans le post dans cette capture d'écran:

Espace supplémentaire

Une petite session de terminal rapide pour dupliquer le problème, avec des commentaires:

$ 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

L'utilisation de la tabulation aurait également complètement évité le problème ici, car bash est assez intelligent pour échapper correctement les espaces (c'est aussi une bonne habitude en général, accélère tellement les chemins de frappe) .

Par exemple, si j'avais tapé rm f<tab>, il se serait complété automatiquement rm foo\<space><space>, comme dans le dernier exemple du bloc de code ci-dessus.

Izkata
la source
Je fais une mention spéciale de copier / coller la lssortie parce que quelque chose de similaire s'est produit sur StackOverflow une fois (et c'est la raison pour laquelle j'ai pensé chercher ceci): quelqu'un a obtenu un caractère non imprimable dans son code, et la seule raison pour laquelle quelqu'un l'a compris est parce que cet utilisateur a également copié / collé au lieu de
retaper
0

une fois, j'ai créé un fichier pour ouvrir Nautilus en tant que root, mais le nom du fichier en voyant depuis nautilus était "File Browser (root)", puis quand j'ai essayé de le supprimer comme

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

la seule réponse que j'ai reçue était: "rm: ne peut pas supprimer 'File Browser (Root) .desktop': Aucun fichier ou répertoire de ce type"

puis quand je cours:

$ ls -l

j'ai vu / retenu que le nom du fichier était en fait "Nautilus-root.desktop"

alors je cours:

$ sudo rm "Nautilus-root.desktop"

travaillé pour moi, j'espère que ça aide!

Wagner Arcieri
la source
0

J'ai donc eu ce problème et aucune de ces choses n'a fonctionné pour moi. Ce qui a fonctionné était de créer un fichier avec exactement le même nom. C'était un dossier nommé Example.1.2.3, j'ai donc créé un nouveau dossier et je l'ai nommé exactement le même que celui qui ne voulait pas être supprimé. L'ancien dossier a disparu et j'ai supprimé le nouveau.

Jamison Lifsey
la source
0

J'ai eu une situation similaire, après avoir utilisé rsyncpour sauvegarder mon répertoire Pictures sur un Mac et l'avoir lu sur Ubuntu. Il y avait deux fichiers (en fait des répertoires) avec des noms différents, mais ayant le même contenu. J'ai supprimé l'un dans la corbeille (à l'aide de Nautilus), mais je n'ai pas pu supprimer l'autre, même depuis la ligne de commande. Cela dirait:

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

Après avoir vérifié les numéros d'inode avec ls -i -l, il s'est avéré que les deux répertoires ont le même numéro d'inode. On dirait un lien dur ...

La solution était étonnamment simple - videz la corbeille en cliquant avec le bouton droit sur l'icône. Après cela, les deux répertoires ont disparu.

elomage
la source