Jak usunąć ten nieusuwalny katalog?

40

Rozpakowałem uszkodzony plik tar i udało mi się skończyć z katalogiem, którego nie mogę usunąć. Jeśli spróbuję go usunąć, wygląda na to, że nie można go znaleźć, ale lspokazuje, że jest obecny, zarówno z bash, jak i python. podobne zachowanie, z wyjątkiem zaraz po tym, jak spróbuję go usunąć rm -rf, lsnarzeka, że ​​nie może go znaleźć, a następnie wyświetla listę (patrz poniżej po rm -rf). findPodaje komunikat, że plik jest obecny, ale nadal nie mogę wymyślić sposób, aby go usunąć.
Oto moje próby:

Tutaj widzisz oba lsi findzgadzasz się, że mamy katalog,

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

Ale nie mogę go usunąć:

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

Mogę cdto zrobić i jest puste:

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


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

patrz poniżej, że nie jest to zwykły plik, ale katalog, plus lszachowuje się zabawnie po tym, rm -rf jak mówi, że nie może znaleźć pliku, a następnie wyświetla go zaraz po:

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

To jest próba z pythonem, plik został znaleziony, ale nazwa nie nadaje się do użycia jako nazwa, którą można usunąć:

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'

nawet gdy używam uzupełniania tabulatorem, nazwa, którą wybiera, nie jest użyteczna:

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

używając nazwy, którą Python pokazuje przy pomocy bash, otrzymuję to:

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

Czy mogę coś zrobić, aby pozbyć się tego zepsutego katalogu? Podstawowy system plików (NFS) wydaje się funkcjonalny i nie zgłoszono żadnych innych problemów, a ja nie miałem takich problemów, dopóki nie został uszkodzony plik tar.

EDYCJA: Oto findwłasna -execopcja, aby zadzwonić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]$

ale plik nadal tam jest ( lsnarzeka, że ​​nie może go znaleźć, ale mimo to pokazuje)

2. EDYCJA:

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

Zachowanie jest nadal niezmienione, plik nadal obecny

3. EDYCJA:

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

Wydaje się, że w nazwie kryje się coś więcej niż tylko mikeaâcntspojrzenie na wynik próby Pythona mikea\xc3\xa2\xc2\x81\xc2\x84cnti ten zrzut ekranu:

Wyjście ls

4. EDYCJA: To jest próba z dziką kartą:

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

i moje ustawienia regionalne:

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. edycja:

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

ale także zachowanie się zmieniło, teraz lsi cd zrób to:

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.

Stało się to po próbach usunięcia, myślę, że mogą to być problemy z NFS, jak sugeruje jedna z odpowiedzi tutaj przez vinc17.

6. EDYCJA: To jest wyjście z lsofils -a

rl] $ / usr / sbin / lsof mikeaâ ^ Á ^ Ęcnt lsof: błąd statusu na mikeaâ \ xc2 \ x81 \ xc2 \ x84cnt: Brak takiego pliku lub katalogu

powyższe jest nieprawidłowe, oto poprawne lsofwywołanie: (rl to katalog nadrzędny)

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-cia Edit: ruch nie będzie działać, (próbowałem go przed tym wszystkim, ale nie uchroniło wyjścia), ale ma ten sam problem jak lsi rm z pliku.

8. EDYCJA: używa sugerowanych znaków szesnastkowych:

 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. edycja: dla statpolecenia:

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

Wydaje się to jeszcze bardziej prawdopodobne na podstawie wszystkich danych wyjściowych, istnieje błąd lub inne niewłaściwe zachowanie NFS, jak sugerowano w komentarzach.

Edycja 10: To jest wyjście strace w gist, ponieważ jest tak duże, jego wyjście lub te dwa polecenia:

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

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

Edycja 11: Tak więc przed powyższym rmdirzauważyłem, że mogę cdwejść do katalogu, ale po tym rmdirnie mogłem cdponownie, podobnie jak wczoraj. Te .i .. pliki były obecne:

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

Ostateczna edycja: widziałem nad tym lokalnego administratora i problem został rozwiązany przez zalogowanie się do samego serwera i usunięcie z niego. Wyjaśnienie z nich jest takie, że może to być problem z niewłaściwymi zestawami znaków w nazwie.

mike-m
źródło
Czy istnieje powód, dla którego wysyłasz finddane wyjściowe do innego polecenia zamiast po prostu używać jego execopcji?
HalosGhost
@HalosGhost nie było powodu, zobacz edycję, aby uzyskać dodatkowe informacje na twoje pytanie
mike-m
2
Jako osoba z bardzo małym doświadczeniem w unixie i linuksie, oto mój pomysł: spróbuj zmienić nazwę katalogu na coś bez użycia tych symboli mv. może potem możesz go usunąć. Alternatywnie możesz spróbować przenieść katalog na głębszy poziom folderu (być może z użyciem symbolu wieloznacznego), a następnie usunąć folder, do którego został przeniesiony.
Nzall
4
Podejrzewam, że katalog istnieje tylko w pamięci klienta i od dawna nie ma go na serwerze. Czy próbowałeś go zamontować i zamontować ponownie? Czy próbowałeś ponownie uruchomić klienta? Czy jest widoczny na innych klientach?
kasperd
6
@ mike-m Wygląda na to, że trafiłeś w błąd NFS, prawdopodobnie na serwerze NFS. Albo to, albo uszkodzenie systemu plików na serwerze. Wątpię, czy naprawdę możesz zrobić coś innego niż czekać, aż administratorzy serwera NFS poradzą sobie z tym.
derobert

Odpowiedzi:

11

Poniższy fragment tego eseju potencjalnie wyjaśnia, dlaczego ten katalog odmawia usunięcia:

NFSv4 wymaga, aby wszystkie nazwy plików były wymieniane za pomocą UTF-8 za pośrednictwem przewodu. Specyfikacja NFSv4, RFC 3530, mówi, że nazwy plików powinny być zakodowane w UTF-8 w sekcji 1.4.3: „W niewielkim odstępstwie nazwy plików i katalogów są kodowane w UTF-8, aby poradzić sobie z podstawami internacjonalizacji.” Ten sam tekst znajduje się również w nowszej wersji NFS 4.1 RFC (RFC 5661) w sekcji 1.7.3. Obecny klient systemu Linux NFS po prostu przekazuje nazwy plików bez żadnych konwersji z bieżących ustawień narodowych do i z UTF-8. Używanie nazw plików innych niż UTF-8 może stanowić prawdziwy problem w systemie korzystającym ze zdalnego systemu NFSv4; każdy serwer NFS zgodny ze specyfikacją NFS ma odrzucać nazwy plików inne niż UTF-8. Więc jeśli chcesz mieć pewność, że twoje pliki mogą być faktycznie przechowywane z klienta Linux na serwerze NFS, musisz obecnie używać nazw plików UTF-8. Innymi słowy,

UTF-8 jest podejściem długoterminowym. Systemy muszą obsługiwać UTF-8, jak również wiele starszych kodowań, dając ludziom czas na przejście na UTF-8. Aby używać „UTF-8 wszędzie”, wszystkie narzędzia muszą zostać zaktualizowane w celu obsługi UTF-8. Lata temu był to duży problem, ale od 2011 r. Jest to zasadniczo rozwiązany problem i myślę, że trajektoria jest bardzo wyraźna dla tych kilku systemów końcowych.

Nie wszystkie sekwencje bajtów są zgodne z UTF-8 i nie musisz wymyślać, jak je wyświetlić. Jeśli jądro wymusza te ograniczenia, upewniając się, że dozwolone są tylko nazwy plików UTF-8, nie ma problemu ... wszystkie nazwy plików będą zgodne z prawem UTF-8. Funkcja C Markusa Kuhna utf8_check może szybko ustalić, czy sekwencja jest poprawna UTF-8.

System plików powinien wymagać, aby nazwy plików spełniały pewne normy, nie z powodu złej potrzeby kontrolowania ludzi, ale po prostu, aby nazwy mogły być zawsze poprawnie wyświetlane później. Brak standardów utrudnia użytkownikom, a nie łatwiej. Jednak system plików nie zmusza nazw plików do UTF-8, więc może łatwo mieć śmieci.

Timothy Martin
źródło
To wydaje się odzwierciedlać wyjaśnienie od lokalnych administratorów, zaznaczę to jako odpowiedź udzieloną przez administratora. Zobacz moją ostatnią edycję
mike-m,
19

Jednym ze sposobów usuwania takich plików / katalogów jest odwołanie do i-węzła.

Aby znaleźć i-węzły dla elementów w bieżącym katalogu:

ls -i
14813568 mikeaâcnt

Aby usunąć to:

find . -inum 14813568 -delete
Nicolai
źródło
zobacz 5. edycję.
mike-m
4
Nie, to nie usuwa plików według ich i-węzłów. Wyszukuje nazwę pliku dla danego i-węzła, a następnie usuwa plik według jego nazwy. Nic na to nie poradzi, ponieważ podjęto już próbę z poprawną nazwą (obok innych prób z nieprawidłową nazwą).
Gilles 'SO - przestań być zły'
@Gilles - technicznie rzecz biorąc, szuka dentysty i-węzłów i zwraca nazwę pliku, ale zgadzam się.
mikeserv
1
@Nicolai mi nie pomaga. Pojawi się komunikat, że katalog nie jest pusty.
diffracteD
1
Tak, hah, zabawna historia na ten temat: plik, który próbuję usunąć, ma ?odniesienie do i-węzła. Jak to usunąć?
Nic Hartley,
7

Nie należy używać znaków innych niż ASCII w wierszu polecenia, ponieważ, jak widać, z jakiegoś powodu niekoniecznie odpowiadają one nazwie pliku (Unicode ma różne sposoby wyrażania liter akcentowanych). Coś jak:

rm -rf mike*

powinien działać, ponieważ nazwa pliku jest generowana bezpośrednio przez powłokę. Ale upewnij się, że jest tylko jedno dopasowanie (zrób echo mike*pierwszy, aby potwierdzić).

Cóż, jeśli cddziała, to nie ma powodu, dla którego powinienem rmlub lspowinienem powiedzieć No such file or directory, aby problem mógł występować na poziomie systemu plików.

Uwaga: Nie używaj lsdo sprawdzania, czy katalog jest pusty, ale ls -a.

Katalog może być nadal używany przez inny proces (w tym jeśli jest to plik cwd jakiegoś procesu). IMHO, dlatego wciąż „istnieje”, ale może powodować błędy, np. Z ls; lsofmoże dać ci trochę informacji, ale w NFS musisz dowiedzieć się, która maszyna z niego korzysta. Zwłaszcza w przypadku NFS może to powodować dziwne błędy. ls -aw katalogu nadrzędnym może .nfs*w niektórych przypadkach wyświetlać pliki / katalogi.

Kiedy dostaniesz:

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

Podejrzewam, że plik nadal istnieje w tabeli katalogów z powodu buforowania NFS i / lub ponieważ jest używany przez inny proces, ale bez powiązanych informacji. Podczas lspróby uzyskania informacji o samym pliku pojawia się błąd, ponieważ sam plik już nie istnieje (znajduje się tylko w tabeli katalogów), stąd wyświetlany błąd. Następnie lswyświetla nazwę pliku, ponieważ znajduje się w tabeli katalogów. Fakt, że masz znaki zapytania w jednym przypadku, ale nie w drugim przypadku, wynika z błędu wyświetlania lsIMHO (niezwiązanego z twoim problemem).

vinc17
źródło
wypróbowałem wcześniej symbol wieloznaczny, nie zadziałał i nie udało mi się opublikować tej próby w moim pytaniu, zaktualizuję z wynikiem
mike-m
Zobacz moją trzecią edycję. IMHO wynika to z NFS (prawdopodobnie nie zepsucia, ale ze złego buforowania) i być może z faktu, że katalog korzysta z innego procesu. W niektórych przypadkach trzeba zrestartować wszystko (serwer i klienci).
vinc17
Może to może wyjaśniać rzeczy, ale nie mogę być pewien, ponieważ nie mam przywilejów, aby zdjąć go na testy. Zobacz 5. edycję.
mike-m
1
@ vinc17 Proszę nie używać „EDYTUJ” w swojej odpowiedzi, ponieważ dla nowego czytelnika nie ma sensu (istnieje już historia edycji)
Bernhard
iv dodał trochę wyników lsof, nie jestem pewien, czy może ci coś powiedzieć,
mike-m
3

Osobiście przetestowane przy użyciu find„s -execdyrektywę:

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

Folder został poprawnie utworzony i poprawnie usunięty.

Jak wskazał @Igeorget , istnieje jeszcze prostsza metoda, jeśli masz GNU find:

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

Przetestowałem również to polecenie i działa ono poprawnie

HalosGhost
źródło
A jeśli używasz GNU's find, istnieje również -deleteopcja.
lgeorget
Zobacz trzecią edycję,
mike-m
1

Wierzę, że miałem ten sam problem. Wcześniej widziałem problem z nazwą pliku . lsw tym przypadku wyświetlał plik jako â??, ale udało mi się go usunąć rm ☃.

Doprowadziło mnie to do następującego sposobu konwersji niewłaściwej nazwy na poprawną:

Najpierw pobierz bajty nazwy pliku:

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

Następnie zdekoduj te bajty jako UTF-8, aby uzyskać punkty kodowe Unicode, używając szesnastkowego wejścia tej witryny, na przykład: 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

Zauważ, że wszystkie znajdują się poniżej granicy bajtów. Otrzymujemy następujące bajty:

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

Jeśli potraktujemy tę sekwencję w UTF-8, otrzymamy:

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

I tak twoja nazwa pliku to:, mikea⁄cntz ułamkiem ułamkowym zamiast zwykłego do przodu. Możesz teraz przekazać tę nazwę do rmdir.

mvdnes
źródło
To genialne, jeśli znów to spotkam, będę o tym pamiętać. dobry. +1
mike-m
0

Po uzyskaniu poprawnego kodu szesnastkowego nazwy pliku / folderu (używając dowolnej metody, którą uznam za stosowną, mogę wybrać ls --show-control-chars | xxd), należy zastosować specjalną konstrukcję, aby adresować takie znaki podczas działania w bash:

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

W przeciwnym razie odwrotne ukośniki są traktowane jak odwrotny waniliowy.

Abel Cheung
źródło
Proszę spojrzeć na moją edycję (8. edycja)
mike-m
@ mike-m Oczywiście, że nie istnieje, ponieważ lszawiera nowy wiersz w danych wyjściowych, a „cnt” jest duplikowane. Może możesz spróbować skopiować i wkleić wiersz w mojej odpowiedzi i sprawdzić, czy jest skuteczny?
Abel Cheung
Nie, wciąż to: `` rl] $ rmdir $ 'mikea \ xc3 \ xa2 \ xc2 \ x81 \ xc2 \ x84cnt' rmdir: nie udało się usunąć `mikeaâ \ 302 \ 201 \ 302 \ 204cnt ': Brak takiego pliku lub katalogu ``
mike-m
W takim przypadku jest to prawdopodobnie połączenie problemu NFS i ustawień regionalnych uniemożliwiających większości narzędzi systemowych przekazywanie niepoprawnych bajtów innych niż UTF8. I wygląda na to, że usunięcie i-węzła pogorszyło sytuację. Na razie jedyny sposób, jaki mogę wymyślić, to ustawienie systemu na środowisko wolne od ustawień narodowych (użyj ustawień regionalnych „C” dla zmiennych env LC_*i LANGenv) i zamontowanie NFS bez żadnych opcji zestawu znaków
Abel Cheung
0

Czy próbowałeś użyciu rm -rf ./mikeaâcntlub rm -rf "./mikeaâcnt"czy ścieżka bezwzględna? Zamiast tego rmspróbuj rmdir ./mikeaâcnt.

walsht
źródło
część problemu polega na tym, że znaki mikeaâcntwydają się nie być nazwą pliku, ale co się ls wyświetla, patrz trzecia edycja
mike-m
0

Czy próbowałeś uzyskać i-węzeł tego pliku za pomocą stat:

stat mike*

To powinno dać ci numer i-węzła (i inne dane), a następnie możesz spróbować go usunąć.

rsuarez
źródło
iv dodał zmianę z statzachowaniem,
mike-m
0

Miałem podobne problemy. Czy masz Gnome, KDE lub Xwindow DM ?. Jeśli otworzysz broser pliku i usuniesz go stamtąd.

To powinno działać.

Chciałbym zobaczyć rozwiązanie z wiersza poleceń, ale w moim przypadku i po stracie dużo czasu próbując wymyślić, jak je usunąć z wiersza poleceń, stwierdziłem, że było to tak proste, jak usunięcie dowolnego innego pliku z nautilus lub każdy inny eksplorator plików (prawda jest taka, że ​​próbowałem tylko z nautilus).

YoMismo
źródło