Как удалить этот неустранимый каталог?

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

используя имя, которое Python показывает с 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-файла.

РЕДАКТИРОВАТЬ: Здесь используется 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и этого скриншота:

выходной сигнал

4-е редактирование: это попытка с подстановочным знаком:

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 , как это предлагается в одном из ответов здесь на vinc17.

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

Седьмое редактирование: перемещение не будет работать (я пробовал это до этого, но не сохранил вывод), но у него та же проблема, что 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
Я подозреваю, что каталог существует только в памяти на клиенте и давно отсутствует на сервере. Вы пытались размонтировать его и установить снова? Вы пытались перезагрузить клиент? Это видно на других клиентах?
Касперд
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). Текущий NFS-клиент Linux просто передает имена файлов напрямую, без какого-либо преобразования из текущей локали в 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 Маркуса Куна может быстро определить, является ли последовательность допустимой UTF-8.

Файловая система должна требовать, чтобы имена файлов соответствовали некоторому стандарту, не из-за злой необходимости контролировать людей, а просто для того, чтобы имена всегда могли правильно отображаться в более позднее время. Отсутствие стандартов усложняет жизнь пользователей, а не облегчает их. Тем не менее, файловая система не заставляет имена файлов быть UTF-8, поэтому она может легко содержать мусор.

Тимоти Мартин
источник
Похоже, это повторяет объяснение от местных администраторов, я отмечу это как ответ, идущий от объяснения администраторов. Смотрите мое окончательное редактирование
mike-m
19

Один из таких способов удаления файлов / каталогов - это их ссылка на узел.

Чтобы найти inode для элементов в текущем каталоге:

ls -i
14813568 mikeaâcnt

Чтобы удалить это:

find . -inum 14813568 -delete
Nicolai
источник
пожалуйста, смотрите 5-е редактирование.
mike-m
4
Нет, это не удаляет файлы по их индоду. Это ищет имя файла для данного inode, а затем удаляет файл по его имени. Это не может помочь, поскольку попытка уже была сделана с правильным именем (наряду с другими попытками с неправильным именем).
Жиль "ТАК - перестань быть злым"
@Gilles - технически, он ищет inode dentry и возвращает имя файла, но я согласен.
mikeserv
1
@ Николай мне не помогает. Справочник не пустое сообщение появляется.
дифрагированного
1
Да, смешная история об этом: файл, который я пытаюсь удалить, имеет ?ссылку на инод. Как вы удалите его тогда?
Фонд Моника иск
7

Вы не должны использовать не-ASCII символы в командной строке, поскольку, как вы могли видеть, по какой-то причине они не обязательно будут соответствовать имени файла (Unicode имеет различные способы выражения букв с акцентом). Что-то типа:

rm -rf mike*

должно работать, так как имя файла напрямую генерируется оболочкой. Но убедитесь, что есть только одно совпадение ( echo mike*сначала сделайте подтверждение).

Что ж, если cdработает, то нет причин, почему rmили lsследует сказать No such file or directory, что проблема может быть на уровне файловой системы.

Примечание: не используйте, lsчтобы найти пустой каталог, но ls -a.

Каталог может по-прежнему использоваться другим процессом (в том числе, если это cwd какого-то процесса). ИМХО, поэтому он все еще «существует», но может привести к ошибкам, например, с ls; lsofможет дать вам некоторую информацию, но с NFS вам нужно выяснить, какая машина его использует. Особенно с NFS, это может привести к странным ошибкам. ls -aв родительском каталоге может показывать вам .nfs*файлы / каталоги в некоторых случаях.

Когда вы получаете:

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

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

vinc17
источник
Я уже использовал подстановочный знак ранее, он не работал, и я не смог опубликовать эту попытку в своем вопросе, обновлю с результатом
mike-m
Смотрите мое третье редактирование. ИМХО, это связано с NFS (возможно, не с повреждением, а с плохим кэшированием) и, возможно, с тем, что каталог используется другим процессом. В некоторых случаях требуется перезагрузить все (сервер и клиенты).
Vinc17
Может быть, это могло бы объяснить вещи, но я не могу быть уверен, так как у меня нет привилегий, чтобы снять его для испытаний. Смотрите 5-е редактирование.
mike-m
1
@ vinc17 Пожалуйста, не используйте «РЕДАКТИРОВАТЬ» в своем ответе, потому что для нового читателя это не имеет смысла (уже есть история редактирования)
Бернхард
Я добавил некоторый вывод 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

Я также проверил эту команду, и она работает правильно

HalosGhost
источник
И если вы используете GNU find, тоже есть -deleteвариант.
lgeorget
Пожалуйста, смотрите 3-е редактирование,
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.

mvdnes
источник
Это гениально, если я увижу это снова, я запомню это. хороший. +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" дублируется. Может быть, вы можете попробовать скопировать и вставить строку в мой ответ и посмотреть, насколько это эффективно?
Абель Чеунг
Нет, все еще так: `` `rl] $ rmdir $ 'mikea \ xc3 \ xa2 \ xc2 \ x81 \ xc2 \ x84cnt' rmdir: не удалось удалить` mikeaâ \ 302 \ 201 \ 302 \ 204cnt ': такого файла или каталога нет `` `
mike-m
В этом случае вполне вероятно сочетание проблемы NFS и локали, не позволяющей большинству системных утилит пропускать некорректные байты, отличные от UTF8. И похоже, что удаление инода ухудшило ситуацию. На данный момент я могу думать только о том, чтобы настроить вашу систему на среду без локали (используйте локаль "C" для переменных LC_*и LANGпеременных env) и смонтировать NFS без каких-либо опций набора символов
Абель Чунг
0

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

walsht
источник
Частично проблема заключается в том, что символы внутри, по- mikeaâcntвидимому, не являются именами файлов, но что ls отображается, см. 3-е правление
mike-m.
0

Вы пытались получить индекс этого файла с помощью stat:

stat mike*

Это должно дать вам номер инода (и другие данные), а затем вы можете попытаться удалить его.

rsuarez
источник
iv добавил редактирование с statповедением,
mike-m
0

У меня были похожие проблемы. У вас есть Gnome, KDE или какой-нибудь Xwindow DM? Если вы откроете файл и откроете его оттуда.

Он должен работать.

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

YoMismo
источник