Як видалити цей незмінний каталог?


40

Я знімав пошкоджений файл tar і мені вдалося закінчити якийсь каталог, який я не можу видалити, якщо я спробую його видалити, здається, його неможливо знайти, але lsпоказує, що він присутній, як з bash, так і з python, я отримую подібна поведінка, окрім одразу після того, як я спробую її видалити rm -rf, lsскаржиться, що не може її знайти, а потім перелічить (див. нижче після rm -rf). findКоманда показує файл присутній, але до сих пір я не можу придумати спосіб , щоб видалити його.
Ось мої спроби:

Тут ви бачите обоє lsі findпогоджуєтесь, що у нас є каталог,

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

Але я не можу її видалити:

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

Я можу cdдо цього, хоча він порожній:

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


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

дивіться нижче, що це не простий файл, а каталог, а також lsведе себе смішно після того, як rm -rf він говорить, що не може знайти файл, а потім перераховує його після:

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

Отже, це спроба з python, файл знайдений, але ім'я не можна використовувати як ім'я, яке можна видалити:

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'

Навіть коли я використовую заповнення вкладки, назву, яку вона вибирає, не можна використовувати:

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

використовуючи ім'я, яке пітон показує з bash, я отримую це:

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

Чи можу я щось зробити, щоб позбутися цього корумпованого режисера? Базова файлова система (NFS) здається функціональною, і про інші проблеми не повідомляється, і я не мав таких проблем до пошкодженого файлу tar.

EDIT: Тут використовується findвласний -execваріант дзвінка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]$

але файл все ще є, ( lsскаржиться, що не може його знайти, але потім все одно показує)

2-е редагування:

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

Поведінка залишається незмінною, файл все ще присутній

3-е редагування:

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

Ім’я, схоже, більше ім'я, ніж mikeaâcntперегляд результату спроби python mikea\xc3\xa2\xc2\x81\xc2\x84cnt, і цей знімок екрана:

ls вихід

Четверте редагування: Це спроба за допомогою шаблону:

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

і мою мову:

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=

5-та редакція:

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

але також поведінка змінилася, зараз lsі cd роби це:

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.

Це сталося після спроб видалення, я думаю, що це можуть бути проблеми NFS, як запропоновано vinc в одному з відповідей тут .

6-е редагування: це вихід lsofіls -a

rl] $ / usr / sbin / lsof mikeaâ ^ Á ^ Äcnt lsof: помилка стану в mikeaâ \ xc2 \ x81 \ xc2 \ x84cnt: такого файлу чи каталогу немає

вище неправильно, ось правильне lsofвиклик: (rl - це батьківський каталог)

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-е редагування: переміщення не буде працювати, (я пробував це перед усім цим, але вихід не зберег), але у нього така ж проблема, як lsі rm з файлом.

8-е редагування: це використання шістнадцяткових символів, як запропоновано:

 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-а редакція: для statкоманди:

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

Це здається ще ймовірнішим з усіх результатів, є помилка чи інша поведінка NFS, як запропоновано в коментарях.

Редагувати 10: Це страйковий вихід у сукупності, оскільки його такий великий, вихідний чи дві ці команди:

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

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

Редагувати 11: Отже, перед тим, як сказане вище, rmdirя помітив, що я можу cdпотрапити в каталог, але після цього rmdirя cdзнову не зміг , як учора. В .і .. файли були присутні:

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

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


Чи є причина, що ви передаєте findвисновок на іншу команду, а не просто використовуєте її execваріант?
HalosGhost

@HalosGhost не було причин, дивіться редагування для додаткової інформації щодо вашого питання
mike-m

2
Оскільки хтось має дуже мало досвіду роботи з Unix та Linux, ось моя ідея: спробуйте перейменувати каталог на щось без використання цих символів mv. можливо, ви можете видалити його після цього. Крім того, ви можете спробувати перемістити каталог на більш глибокий рівень папки (можливо, за допомогою підстановки), а потім видалити папку, в яку ви перемістили її.
Nzall

4
Я підозрюю, що каталог існує лише в пам'яті клієнта і його давно немає на сервері. Ви спробували вичислити його і знову встановити? Ви спробували перезавантажити клієнта? Це видно на інших клієнтах?
kasperd

6
@ mike-m Це здається, що ви потрапили в помилку NFS, ймовірно, на сервері NFS. Або це, або файлова система пошкоджена на сервері. Я сумніваюся, що ви можете зробити щось інше, окрім як чекати, коли адміністратори серверів NFS вирішать це.
дероберт

Відповіді:


11

Наступний уривок із цього реферату потенційно пояснює, чому цей каталог відмовляється видаляти:

NFSv4 вимагає, щоб усі імена файлів були обмінені за допомогою UTF-8 по дроту. Специфікація NFSv4, RFC 3530, говорить, що імена файлів повинні бути кодовані UTF-8 у розділі 1.4.3: "У невеликому від'їзді назви файлів та каталогів кодуються UTF-8, щоб мати справу з основами інтернаціоналізації". Цей же текст також знаходиться в новій версії 1.7.3 NFS 4.1 RFC (RFC 5661). Поточний клієнт Linux NFS просто передає назви файлів прямо, без будь-якого перетворення з поточної мови в та з UTF-8. Використання імен файлів, що не належать до UTF-8, може бути справжньою проблемою в системі, що використовує віддалену систему NFSv4; будь-який сервер NFS, який відповідає специфікації NFS, повинен відхиляти імена файлів, що не належать до UTF-8. Отже, якщо ви хочете переконатися, що ваші файли можуть бути фактично збережені з клієнта Linux на сервері NFS, ви повинні використовувати файли UTF-8. Іншими словами,

UTF-8 - це довгостроковий підхід. Системи повинні підтримувати UTF-8, а також багато старих кодувань, даючи людям час перейти на UTF-8. Щоб використовувати "UTF-8 скрізь", усі інструменти потрібно оновити для підтримки UTF-8. Роки тому це була велика проблема, але станом на 2011 рік це, по суті, вирішена проблема, і я думаю, що траєкторія дуже чітка для цих кількох задніх систем.

Не всі послідовності байтів є законними UTF-8, і вам не потрібно розбиратися, як їх відображати. Якщо ядро ​​виконує ці обмеження, гарантуючи, що дозволені лише імена файлів UTF-8, тоді немає жодних проблем ... всі назви файлів будуть законними UTF-8. Функція utf8_check C Markus Kuhn може швидко визначити, чи є послідовність дійсною UTF-8.

Файлова система повинна вимагати, щоб назви файлів відповідали якомусь стандарту, не через якусь злу потребу в управлінні людьми, а просто для того, щоб імена завжди могли правильно відображатись у більш пізній час. Відсутність стандартів ускладнює роботу користувачів, а не простіше. Однак файлова система не змушує назви файлів бути UTF-8, тому в ній легко є сміття.


Це, здається, перегукується з поясненнями місцевих адміністраторів, я позначу це як відповідь поясненням адміністраторів. Дивіться мою остаточну редакцію
mike-m

19

Один із способів видалення таких файлів / каталогів - їх inode-посилання.

Щоб знайти вставки для елементів у поточному режимі:

ls -i
14813568 mikeaâcnt

Щоб видалити це:

find . -inum 14813568 -delete

будь ласка, дивіться 5-ту редакцію.
mike-m

4
Ні, це не видаляє файли за їх inode. Це шукає ім'я файлу для даного inode, а потім видаляє файл за його ім'ям. Тут не може допомогти, оскільки спроба вже була зроблена з правильною назвою (поряд з іншими спробами з неправильним іменем).
Жил "ТАК - перестань бути злим"

@Gilles - технічно він шукає зубний протез inode і повертає ім'я файлу, але я згоден.
mikeserv

1
@Nicolai не допомагає мені. Повідомлення не порожнє повідомлення з'являється.
diffracteD

1
Ага, га, смішна історія з цього приводу: Файл, який я намагаюся видалити, має ?посилання на inode. Як потім видалити його?
Нік Хартлі

7

Не слід використовувати символи, що не належать до ASCII, у командному рядку, оскільки, як ви могли бачити, вони чомусь не обов'язково відповідають імені файлу (Unicode має різні способи вираження наголошених літер). Щось на зразок:

rm -rf mike*

має працювати, оскільки ім'я файлу безпосередньо генерується оболонкою. Але переконайтеся, що є лише одна відповідність ( echo mike*спочатку підтвердьте).

Ну, якщо cdпрацює, то немає ніяких причин , чому rmабо lsповинен сказати No such file or directory, так що проблема може бути на рівні файлової системи.

Примітка. Не використовуйте lsдля пошуку, чи каталог порожній, але ls -a.

Каталог все ще може використовуватися іншим процесом (у тому числі, якщо це cwd деякого процесу). IMHO, тому він все ще "існує", але може створювати помилки, наприклад, з ls; lsofможе дати вам деяку інформацію, але з NFS вам потрібно знайти, яка машина використовує її. Особливо це стосується NFS, це може призвести до дивних помилок. ls -aв батьківському .nfs*каталозі в деяких випадках можуть відображатися файли / каталоги.

Коли ви отримаєте:

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

Я підозрюю, що файл все ще існує в таблиці директорій через кешування NFS та / або тому, що він використовується іншим процесом, але без пов’язаної інформації. Коли lsнамагається отримати інформацію про сам файл, він отримує помилку, оскільки сам файл більше не існує (він є лише в таблиці директорій), отже, відображається помилка. Потім lsвиводить ім'я файлу, оскільки воно знаходиться в таблиці директорій. Те, що у вас є знаки запитання в одному випадку, але не в іншому, пов’язане з помилкою відображення lsIMHO (не пов’язаною з вашою проблемою).


я раніше спробував підстановку, вона не спрацювала, і мені не вдалося опублікувати цю спробу в своєму запитанні, я оновлю з результатом
mike-m

Дивіться мою третю редакцію. IMHO це пов'язано з NFS (можливо, це не корупція, але поганий кешування) і, можливо, той факт, що інший процес використовує каталог. У деяких випадках потрібно перезавантажити все (сервер і клієнти).
vinc17

Можливо, це могло б пояснити речі, але я не можу бути впевнений, оскільки я не маю привілеїв, щоб зняти його на тести. Дивіться 5-ту редакцію.
mike-m

1
@ vinc17 Будь ласка, не використовуйте "EDIT" у своїй відповіді, тому що для нового читача це не має сенсу (історія редагування вже є)
Bernhard

iv додав деякий вихід lsof, не впевнений, чи може він сказати тобі що-небудь,
mike-m

3

Я особисто перевірив , використовуючи find«s -execдирективу:

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

Папка була правильно створена та правильно видалена.

Як вказував @Igeorget , є ще простіший метод, якщо у вас є GNU find:

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

Я також перевірив цю команду, і вона працює правильно


І якщо ви використовуєте знахідку GNU, є також -deleteваріант.
lgeorget

Будь ласка, дивіться третю редакцію,
mike-m

1

У мене була така ж проблема, я вважаю. Я раніше бачив проблему з іменем файлу . lsу цьому випадку файл відображався як â??, але я зміг його видалити за допомогою rm ☃.

Це призвело до наступного способу перетворення неправильного імені у правильне:

Спочатку отримайте байти імені файлу:

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

Потім розшифруйте ці байти як UTF-8, щоб отримати кодові точки unicode, використовуючи шістнадцятковий вхід цього веб-сайту, наприклад: 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

Зауважте, що всі вони розташовані нижче межі байта. Отримуємо такі байти:

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

Якщо ми обробляємо цю послідовність у UTF-8, ми отримуємо:

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

Отже, ваше ім'я файлу:, mikea⁄cntз косою фракцією замість звичайної вперед. Тепер ви можете передати це ім'я rmdir.


То геніальне, якщо я зустрінусь із цим ще раз, то маю це на увазі. хороший. +1
mike-m

0

Отримавши правильний шістнадцятковий код імені файлу / папки (використовуючи будь-який метод, який я вважаю за потрібне, я можу вибрати ls --show-control-chars | xxd), слід використовувати якусь спеціальну конструкцію для адреси таких символів при запуску під bash:

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

В іншому випадку нахил від косоокості розглядається як ванільний нахил.


Перегляньте мою редакцію (8-а редакція)
mike-m

@ mike-m Звичайно, це не існує, оскільки lsвключає вихідний рядок у вихідні дані, а "cnt" дублюється. Можливо, ви можете спробувати безпосередньо скопіювати та вставити рядок у мою відповідь і побачити, чи це ефективно?
Abel Cheung

Ні, ще це: `` `rl] $ rmdir $ 'mikea \ xc3 \ xa2 \ xc2 \ x81 \ xc2 \ x84cnt' rmdir: не вдалося видалити` mikeaâ \ 302 \ 201 \ 302 \ 204cnt ': такого файлу чи каталогу немає `` `
mike-m

У такому випадку цілком ймовірно, що поєднання проблеми NFS та локальної локальної системи, що перешкоджає більшості системних утиліт передавати неправильні не-UTF8 байти. І схоже на те, що видалення індексу погіршило ситуацію. Наразі єдиний спосіб, який я можу придумати, - це налаштування вашої системи на середовище без локалів (використовуйте "C" для змін LC_*і LANGenv змінних) та монтуйте NFS без будь-яких варіантів набору символів
Abel Cheung

0

Ви спробували використовувати rm -rf ./mikeaâcntабо rm -rf "./mikeaâcnt"абсолютний шлях? Також замість цього rmспробуйте rmdir ./mikeaâcnt.


частина проблеми полягає в тому, що символи у, mikeaâcntздається, не є ім'ям файлу, а тим, що ls відображається, див. 3-е редагування
mike-m

0

Ви спробували отримати inode цього файлу за допомогою stat:

stat mike*

Це повинно дати вам номер inode (та інші дані), і тоді ви можете спробувати видалити його.


iv додав редагування з statbehavour,
mike-m

0

У мене були подібні проблеми. У вас є Gnome, KDE або якийсь Xwindow DM ?. Якщо ви відкриєте свій файловий браузер і видаліть файл звідти.

Це має працювати.

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

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