"Немає такого файлу чи каталогу" при спробі видалити файл, але файл існує?


21

Я намагаюся видалити PNG-зображення, яке було завантажено на мій сервер через скрипт PHP. Кожного разу, коли я намагаюся видалити його як через ftp, так і через термінал, я отримую помилку

No such file or directory

Однак, коли я перебуваю lsв режимі dir, файл перераховується, і він також вказаний у моєму ftp-клієнті. Я спробував створити файл з тим самим іменем, і я отримав два файли з тим самим іменем.

Я можу відкрити файл, який нібито не існує, але все одно не можу його видалити. Я також спробував перезавантажити свій сервер. Будь-які ідеї, що може бути проблемою? Я використовую 64-бітну версію Ubuntu, але я не думаю, що це 32/64 бітова проблема. Я також повинен зазначити, що я видалив багато інших файлів png, завантажених тим самим PHP-скриптом.

Вихід для 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

Вихід при спробі rm

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

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


Скопіюйте вставити вихід ls -lз каталогу, також повну rmкоманду та її вихід ..
heemayl

@heemayl всього 224 -rw-r - r-- 1 www-data www-data 222838 13 травня 04:14 qyxdshyikfr_fishing_timeout.png -rw-r - r-- 1 корінь кореня 272 травня 14 06:54 upload.php rm: не можна видалити 'qyxdshyikfr_fishing_timeout.png': Немає такого файлу чи каталогу
DevinFrench

1
@DevinFrench, будь ласка, відредагуйте своє запитання, щоб додати інформацію.
муру

З якого каталогу ви запускаєте rmкоманду?
heemayl

1
@Samuel Чому це запропонує проблему з файловою системою? unlinkВиклик завжди буде не в змозі знайти файл , який не існує. Коли я запускаю цю straceкоманду в своїй системі, де я знаю, що у мене немає такого файлу, він видає подібний вихід; Я не думаю, що це означає, що у мене проблема з файловою системою! Набагато ймовірніше, що ім'я файлу дещо відрізняється від qyxdshyikfr_fishing_timeout.pngі просто видається таким же через обмеження в способі lsвідображення імен файлів, як це пропонується в інших відповідях.
Елія Каган

Відповіді:


21

Я спробував створити файл з тим самим іменем, і я отримав два файли з тим самим іменем.

Це говорить про відсутність пошкодження файлової системи, що у вас є два файли з двома різними іменами, які виглядають однаково через недрукувальних символів або символів, які виглядають однаково у наборі символів / шрифті. Можливо, --escapeщоб lsваш друг у таких випадках, як і такі інструменти, як cat -v.

Так само і є rm -i -- *

Подальше читання


Я був автором файлу та ім'ям файлу, який було завантажено. Ніхто не намагався саботувати мій сервер, оскільки я єдина людина, яка знає повний шлях до upload.php. Однак, rm -i -- *зробила трюк.
ДевінФренч

3
@DevinFrench Якщо ця відповідь вирішила вашу проблему, будь-ласка, позначте її як прийняту відповідь, натиснувши позначку під підрахунком оновлень, щоб майбутні користувачі могли знати про те, що це рішення працювало на вас.
kos

1
Чи може хтось пояснити rm -i -- *команду?
користувач3731622

З того, що я розумію: Проходження -i підкаже вам перед видаленням кожного файлу. --перш ніж *вибирати всі файли незалежно від того, чи містять їх імена спеціальні символи. Довідка: https://explainshell.com/explain?cmd=rm+-i+--+*
MoltenMuffins

16

TL; DR: запустіть ls -1b, знайдіть ім'я файлу, скопіюйте рядок, у якому він з’являється, і надайте цьому rm.

Як зазначають інші, найімовірніше, це пов'язано з обмеженнями в способі ls- і деякі інші програми, включаючи клієнтське та серверне програмне забезпечення - за замовчуванням обробляють дивні назви файлів, наприклад, що містять контрольні символи. Ваш успіх у відповіді JdeBP настійно говорить про те, що це було так, хоча це було б добре робити ще до цього.

  • Тому що ls, коли стандартний вихід є терміналом, ?символи друкуються на їх місці. Отже, якщо ви не переносите lsвихід на будь-яку іншу команду (або перенаправляєте її в журнал для перегляду), можливо, ваше ім'я файлу не містить контрольних символів. Але є й інші проблемні символи - можливо, ім'я файлу містить, наприклад, пробіли.

    Така поведінка lsможе бути заплутаною, але не є помилкою, її можна явно перекрити користувачем (див. Нижче).

  • При спробі отримати доступ або видалити файл віддалено, помилки в клієнтському або серверному програмному забезпеченні можуть спричинити такі проблеми.

    Я вже ftpдекілька разів переживав подібні речі , зокрема для файлів, імена яких містять пробіли. (Щоб це не спрацювало, було пов’язано з помилкою в моєму ftp-клієнті.) Навіть коли ви вручну створюєте файл самостійно, залежно від того, як ви його створюєте, іноді досить просто ненароком вставити проміжок простору чи інший пробіл, який може виглядати як пробіли, хоча це не так.

Це ситуація, коли ls -1b(або dir -1) стане в нагоді:

  • -1повідомляє lsпоказувати один запис на рядок. Таким чином, немає плутанини щодо того, де закінчується одна назва файлу, а інша починається. Це зручно для дивно названих файлів.
  • -bповідомляє lsнадрукувати послідовності втечі для будь-яких спеціальних символів. Вихідні дані ls -bможуть бути скопійовані і вставлені буквально в команду, без додавання цитування : всі проблемні символи вже цитуються таким чином, що оболонка розпізнає їх такими, якими вони є.

Є лише одне застереження: якщо видається останній символ у рядку \, скопіюйте один символ після цього, оскільки це означає \цитування пробілу.

Ви можете запустити ls -1bтак само, або ви можете передати йому шаблон глобальної оболонки (наприклад, ls -1b qyx*). Глоббінг може або не може знайти файл, залежно від того, чи є контрольні символи (або інші дивні символи) присутні у частині імені, що відображається у шаблоні глобуса.

Скопіювавши \котирувану версію імені файлу, яку вам дали ls, ви можете вставити це в команду. Вам не потрібно змінювати його вручну жодним чином. У вашому випадку, як ви хочете видалити файл, наберіть rm, введіть пробіл, вставте рядок і натисніть Enter.

Подальше читання:


1
Дуже круто -bthx =) і +1
AB

Щось я залишив поза ОП, коли я створив файл з тим самим іменем, у своєму ftp-клієнті, коли я намагався видалити перший файл, у якого виникли проблеми, він замість цього видалив новий файл, який я створив. Ось чому я не думав, що якісь особливі персонажі були залучені, і я досі не знаю, яким був особливий персонаж з моменту використання rm -i -- *.
ДевінФренч

@DevinFrench Додатковий символ - пробіл на кінці імені файлу. Він все ще знаходиться у lsвихідному запитанні, але його можна побачити в текстовому режимі лише при натисканні кнопки "редагувати".
Ізката

@Izkata Добрий дзвінок! Я повинен був подумати, щоб це перевірити. Це також з'являється, коли я розширюю версію 3 в історії редагування (повне ім'я файлу, включаючи пробіл, виділяється зеленим кольором і, таким чином, помітно). Те, що ви сказали, є найбільш остаточним і конкретно правильним поясненням на даний момент - якщо ви опублікували відповідь, в якій пояснювали, що це з пробілу, і як ви знаєте, і яка команда видалить файл (якщо в ОП це все ще було) , Я знаю, що я підтримав це.
Елія Каган

@EliahKagan Готово, із зображеннями
Ізката

3
  1. Використовуйте findта перевіряйте вихід:

    Якщо файл не знайдено, *qyxdshyikfr*трохи скорочуйте пошуковий термін , наприклад: *qyxds*або *fishing*.

    sudo find . -maxdepth 1 -type f -name "*qyxdshyikfr*"
    
  2. Якщо добре, тоді використовуйте findпошуковий термін на кроці 1 таrm

    find . -maxdepth 1 -type f -name "*qyxdshyikfr*" -print0 | xargs -0  rm
    

1
Замість того , щоб викликати rmпо імені по трубі від findдо xargs, я рекомендую просто використовувати find«s -deleteдії. Також sudoне потрібно. Менш значущо, я пропоную пропустити, -type fза винятком випадків, коли це явно корисно. Імовірно, якщо запис, який ОП хоче видалити, виявився символічним посиланням, наприклад, вони все одно захочуть його знайти і все ще хочуть його видалити. -deleteДія не буде рекурсивно затирати каталог; і ваша rmкоманда не буде, оскільки у вас її немає -r. Таким чином, ви не збираєтеся випадково зірвати цілу (не порожню) папку, не використовуючи -type.
Елія Каган

Гаразд, дайте мені секунду.
AB

У моєму випадку навіть find ... -deleteсказано "не можна видалити ... Немає такого файлу чи каталогу"
Зупиніть шкодити Моніці

1

Докладно репостуючи, розширився з мого коментаря до відповіді Іллі

Проблема невидима, але її можна помітити, якщо ви знаєте, що шукати: Ім'я файлу містить пробіл в кінці. Оскільки ви копіюєте / вставляєте весь lsвихід, це можна побачити у запитанні, якщо ви виділите висновок, чи відредагуєте публікацію та перемістіть курсор до кінця, або (як вказував Елія) перегляньте розріз в історії редагування. На lsцьому скріншоті я виділив вихід у публікації:

Додатковий простір

Швидкий невеликий термінальний сеанс для дублювання проблеми з коментарями:

$ 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

Використання заповнення вкладок також би повністю усунуло проблему тут, оскільки bash досить розумний, щоб правильно уникнути пробілів (Це також хороша звичка загалом, настільки прискорює введення шляхів) .

Наприклад, якби я набрав rm f<tab>, це було б автоматично завершено rm foo\<space><space>, як і в останньому прикладі в кодовому блоці вище.


Я спеціально згадую про копіювання / вставлення lsвиводу, тому що щось подібне трапилося в StackOverflow одного разу (і це ціла причина, що я думав це шукати): хтось отримав недрукувальний символ у своєму коді, і єдина причина, коли хтось зрозумів це це тому, що цей користувач також копіює / вставляє замість повторного введення коду під час публікації запитання
Ізката

0

одного разу я створив файл, щоб відкрити Nautilus як root, але ім'я файлу при nautilus було "Переглядач файлів (root)", то коли я намагався видалити як

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

єдиний я отримав: "rm: не можна видалити" Файл-браузер (Root) .desktop ": такого файлу чи каталогу немає"

то коли я біжу:

$ ls -l

я бачив / пам’ятав, що ім’я файлу, власне, було «Nautilus-root.desktop»

тому я бігаю:

$ sudo rm "Nautilus-root.desktop"

працював на мене, сподіваюся, що це допомагає!


0

Тож у мене була ця проблема, і жодне з цих речей не працювало на мене. Що працювало, це створити файл з точно такою ж назвою. Це була папка з назвою Example.1.2.3, тому я створив нову папку і назвав її точно такою ж, яку не видаляв. Стара папка зникла, і я видалив нову.


0

У мене була схожа ситуація після використання rsyncрезервного копіювання каталогу Photos на Mac та читання його на Ubuntu. Були два файли (фактично каталоги) з різними іменами, але мають однаковий вміст. Я видалив одну з кошика (за допомогою Nautilus), але не зміг видалити іншу, навіть із командного рядка. Він би сказав:

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

Після перевірки номерів inode за допомогою ls -i -l виявилося, що обидва каталоги мають однакове число inode. Схоже, міцне посилання ...

Рішення було напрочуд простим - випорожніть Кошик, клацнувши правою кнопкою миші на піктограму. Після цього обох каталогів не було.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.