W jakiś sposób jedno z naszych starych serwerów Server 2008 (nie R2) opracowało folder, który wydaje się nieskończenie cykliczny. To grozi spustoszeniem dzięki naszym kopiom zapasowym, ponieważ agent tworzenia kopii zapasowych próbuje powrócić do folderu i nigdy nie wraca.
Struktura folderów wygląda mniej więcej tak:
C:\Storage\Folder1
C:\Storage\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1\Folder1
... i tak dalej. To jak jeden z tych zestawów Mandelbrot, z którymi wszyscy bawiliśmy się w latach 90-tych.
Próbowałem:
- Usuwanie go z Eksploratora. Tak, jestem optymistą.
RMDIR C:\Storage\Folder1 /Q/S
- to powracaThe directory is not empty
ROBOCOPY C:\temp\EmptyDirectory C:\Storage\Folder1 /PURGE
- powoduje to wirowanie folderów przez kilka minut przed awarią robocopy.exe.
Czy ktoś może zasugerować sposób na dobre zabicie tego folderu?
/MIR
zamiast tego:ROBOCOPY /MIR C:\temp\EmptyDirectory C:\Storage\Folder1
być może warto uruchomićchkdsk
tylko na chichoty./MIR
wydawało się, że trwa dłużej, ale ostatecznie też zbombardował („robocopy przestało działać”). Trochę boję się zrobićchkdsk
; to dość stary serwer i martwię się, że ten problem wskazuje na większe problemy z systemem plików ...find
do pierwszego głębokiego usunięcia katalogu:find Storage/Folder1 -depth -exec rmdir {} \;
Odpowiedzi:
Dziękujemy wszystkim za przydatną poradę.
Wchodząc dobrze na terytorium StackOverflow, rozwiązałem problem, wyrzucając ten fragment kodu C #. Korzysta z biblioteki Delimon.Win32.IO, która konkretnie rozwiązuje problemy z dostępem do długich ścieżek plików.
Na wypadek, gdyby to pomogło komuś innemu, oto kod - przeszedł przez ~ 1600 poziomów rekurencji, z którą jakoś utknąłem i zajęło mi około 20 minut, aby je wszystkie usunąć.
źródło
.Delete
(zamiast zwykłejSystem.IO
wersji) i chociaż nie rzucało to wyjątku, nie wydawało się, że nic nie robi. Z pewnością rekursja przy użyciu powyższej metody trwała wieki i.Delete
żuł rzeczy tylko przez 5-10 sekund. Może odłamał się w kilku katalogach, a potem się poddał?Może być rekurencyjnym punktem połączenia. Taką rzecz można utworzyć za
junction
pomocą narzędzia do obsługi plików i dysków Sysinternals .I możesz teraz bez końca iść w dół c: \ Hello \ Hello \ Hello .... (aż do osiągnięcia MAX_PATH, 260 znaków dla większości poleceń, ale 32 767 znaków dla niektórych funkcji Windows API).
Lista katalogów pokazuje, że jest to skrzyżowanie:
Aby usunąć, użyj narzędzia do łączenia:
źródło
DIR
właśnie pokazuje mi zwykłe katalogi - nie boję się żadnych skrzyżowań - obawiam sięjunction -s C:\Storage\Folder1
?No reparse points found
:(dir /a
aby zobaczyć „<JUNCTION>” bez podawania konkretnej nazwy.Brak odpowiedzi, ale nie mam wystarczającej liczby przedstawicieli do komentarza.
Kiedyś naprawiłem ten problem na ogromnej wówczas 500 MB płycie FAT16 w systemie MS-DOS. Użyłem debugowania DOS, aby ręcznie zrzucić i przeanalizować tabelę katalogów. Następnie odwróciłem jeden bit, aby zaznaczyć katalog rekurencyjny jako usunięty. Moja kopia Dettmana i Wyatta „DOS Programmers” Reference ”wskazała mi drogę.
Nadal jestem z tego niezwykle dumny. Byłbym zaskoczony i przerażony, gdyby istniało jakieś narzędzie ogólnego przeznaczenia, które ma taką moc nad woluminami FAT32 lub NTFS. Życie było wtedy prostsze.
źródło
Java może również radzić sobie z długimi ścieżkami plików. I może to zrobić znacznie szybciej. Ten kod (który skopiowałem z dokumentacji Java API) usunie strukturę katalogu głębokiego na poziomie 1600 w około 1 sekundę (pod Windows 7, Java 8.0) i bez ryzyka przepełnienia stosu, ponieważ tak naprawdę nie używa rekurencji.
źródło
Nie potrzebujesz długich nazw ścieżek, jeśli wchodzisz
chdir
do katalogu i po prostu używasz ścieżek względnych dormdir
.Lub, jeśli masz zainstalowaną powłokę POSIX lub przenieś ją do odpowiednika DOS:
(Użycie zmiennej powłoki do śledzenia miejsca, w którym została zmieniona jej nazwa dla warunku pętli, jest inną alternatywą dla rozwijania pętli, jak tam.)
Pozwala to uniknąć obciążenia procesora przez rozwiązanie KenD, które zmusza system operacyjny do przechodzenia przez drzewo od góry do
n
poziomu th za każdym razem, gdy dodawany jest nowy poziom, sprawdzania uprawnień itp. Ma więcsum(1, n) = n * (n-1) / 2 = O(n^2)
złożoność czasową. Powinny istnieć rozwiązania, które oddzielają fragment od początku łańcuchaO(n)
, chyba że system Windows musi przejść przez drzewo podczas zmiany nazwy katalogu nadrzędnego. (Linux / Unix nie.) Rozwiązania,chdir
którechdir
sięgają do samego końca drzewa i używają stamtąd ścieżek względnych, usuwając katalogi podczas tworzenia kopii zapasowej, powinny również byćO(n)
, zakładając, że system operacyjny nie musi sprawdzać wszystkich katalogi nadrzędne każde wywołanie systemowe, gdy robisz coś, gdy gdzieś jest CD.find Folder1 -depth -execdir rmdir {} +
uruchomi rmdir podczas zapisywania CD do najgłębszego katalogu. A właściwie-delete
opcja find działa na katalogach i implikuje-depth
.find Folder1 -delete
Powinien więc zrobić dokładnie to samo, ale szybciej. Tak, GNU find w Linuksie schodzi przez skanowanie katalogu, CDing do podkatalogów ze ścieżkami względnymi, a następniermdir
ścieżką względnąchdir("..")
. Nie skanuje ponownie katalogów podczas wstępowania, więc zużywaO(n)
pamięć RAM.To było naprawdę przybliżenie:
strace
pokazy faktycznie korzystaunlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
,open("..", O_DIRECTORY|...)
orazfchdir(the fd from opening the directory)
z grupąfstat
połączeń mieszane, też. Ale efekt jest taki sam, jeśli drzewo katalogów nie jest modyfikowane podczas działania funkcji find.edycja: Tylko dla kopnięć próbowałem tego na GNU / Linux (Ubuntu 14.10, na pierwszej generacji procesorze Core2Duo pierwszej generacji 2,4 GHz, na systemie plików XFS na dysku WD 2.5TB Green Power (WD25EZRS)).
(mkdir -p tworzy katalog i wszelkie brakujące elementy ścieżki).
Tak, naprawdę 0,05 sekundy na 2k rmdir ops. xfs jest całkiem dobry w grupowaniu operacji na metadanych w czasopiśmie, ponieważ naprawiono powolne operacje metadanych, jak 10 lat temu.
Na ext4 tworzenie zajęło 0m0,279s, usunięcie z szukaniem wciąż zajęło 0m0,074s.
źródło
Zetknąłem się z tym samym problemem związanym z katalogiem o głębokości katalogów ponad 5000, co niektóre aplikacje Java, i napisałem program, który pomoże ci usunąć ten folder. Cały kod źródłowy znajduje się w tym linku:
https://imanolbarba.net/gitlab/imanol/DiREKT
Po pewnym czasie to wszystko usunęło, ale udało się to zrobić, mam nadzieję, że pomoże ludziom, którzy (tak jak ja) napotykają ten sam frustrujący problem
źródło
Ja też to miałem, w samodzielnym systemie Windows 10. C: \ Użytkownik \ Nazwa \ Powtórz \ Powtórz \ Powtórz \ Powtórz \ Powtórz \ Powtórz \ Powtórz pozornie do nieskończoności.
Mógłbym nawigować za pomocą Windowsa lub wiersza polecenia do około 50. i nie dalej. Nie mogłem go usunąć ani kliknąć, itp.
C jest moim językiem, więc w końcu napisałem program z pętlą wywołań systemowych, które powtarzają się aż do niepowodzenia. Możesz to jednak zrobić w dowolnym języku, nawet partię DOS. Zrobiłem katalog o nazwie tmp i przeniosłem do niego Repeat \ Repeat, usunąłem teraz pusty folder Repeat i przeniosłem tmp \ Repeat z powrotem do bieżącego folderu. W kółko!
ChkSystem po prostu uruchamia wywołanie system () i sprawdza wartość zwracaną, zatrzymując się, jeśli się nie powiedzie.
Co ważne, zawiodło wiele razy. Myślałem, że może mój program nie działa lub że mimo wszystko był nieskończenie długi. Jednak miałem to już wcześniej przy wywołaniach systemowych, przy czym rzeczy się nie synchronizowały, więc po prostu ponownie uruchomiłem program i kontynuowałem od miejsca, w którym został przerwany, więc nie myśl od razu, że twój program nie działa. W sumie, po uruchomieniu go około 20 razy, wyczyścił je wszystkie. W sumie pierwotnie miało około 1280 folderów. Nie mam pojęcia, co to spowodowało. Zwariowany.
źródło