Próbuję usunąć katalog rekurencyjnie rm -Force -Recurse somedirectory
, otrzymuję kilka błędów „Katalog nie jest pusty”. Jeśli powtórzę to samo polecenie , to się powiedzie.
Przykład:
PS I:\Documents and Settings\m\My Documents\prg\net> rm -Force -Recurse .\FileHelpers
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests\Data\RunTime\_svn: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (_svn:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests\Data\RunTime: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (RunTime:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests\Data: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (Data:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\FileHelpers.Tests: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (FileHelpers.Tests:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\Libs\nunit\_svn: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (_svn:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\Libs\nunit: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (nunit:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers\Libs: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (Libs:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
Remove-Item : Cannot remove item I:\Documents and Settings\m\My Documents\prg\net\FileHelpers: The directory is not empty.
At line:1 char:3
+ rm <<<< -Force -Recurse .\FileHelpers
+ CategoryInfo : WriteError: (I:\Documents an...net\FileHelpers:DirectoryInfo) [Remove-Item], IOException
+ FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
PS I:\Documents and Settings\m\My Documents\prg\net> rm -Force -Recurse .\FileHelpers
PS I:\Documents and Settings\m\My Documents\prg\net>
Oczywiście nie zawsze tak się dzieje . Ponadto nie dzieje się tak tylko w przypadku _svn
katalogów i nie mam pamięci podręcznej TortoiseSVN ani niczego podobnego, więc nic nie blokuje katalogu.
Jakieś pomysły?
źródło
@JamesCW: Problem nadal występuje w PowerShell 4.0
Próbowałem innego obejścia i zadziałało: użyj cmd.exe:
źródło
iisreset
przed usunięciem i nic nie działa niezawodnie . Spróbuję tego, chociaż kiedy go zobaczyłem, nie chciałem mieć DOS-a wewnątrz mojej PowerShell ...rd /s
również zawiesza się sporadycznie (choć pozornie rzadziej niżRemove-Item
): github.com/Microsoft/console/issues/309ETA 20181217: W niektórych okolicznościach PSVersion 4.0 i nowsze nadal będą zawierane, zobacz alternatywną odpowiedź Mehrdada Mirrezy i raport o błędach złożony przez mklement
mklement zapewnia rozwiązanie Proof of Concept przy tej odpowiedzi SO , ponieważ błąd oczekuje na oficjalną poprawkę
Nowa wersja
PowerShell
(PSVersion 4.0
) całkowicie rozwiązała ten problem iRemove-Item "targetdirectory" -Recurse -Force
działa bez problemów z synchronizacją.Możesz sprawdzić swoją wersję, uruchamiając
$PSVersiontable
z poziomu ISE lubPowerShell
monitu. 4.0 to wersja dostarczana zWindows 8.1
iServer 2012 R2
, i można ją również zainstalować w poprzednich wersjach systemu Windows.źródło
rd
wersji. Poza faktycznym działaniem jest około 3 razy szybszyrd /s
rzadziej może zawieść, to też jest zepsuty - zobacz ten raport o błędzie .Aktualizacja : pozornie istnieją plany synchronizacji interfejsów API usuwania systemu plików Windows, ale nie są one jeszcze synchroniczne od wersji Windows 10 1903 - zobacz ten komentarz na GitHub .
Istniejące odpowiedzi łagodzą problem, dzięki czemu występuje rzadziej, ale nie dotyczą pierwotnej przyczyny , dlatego nadal mogą występować awarie.
Remove-Item -Recurse
jest nieoczekiwanie asynchroniczny , ponieważ metody Windows API do usuwania plików i katalogów są z natury asynchroniczne iRemove-Item
nie uwzględniają tego.Ten sposób przerywany, nieprzewidywalnie przejawiająca się w jednej z dwóch sposobów:
Twój przypadek: Samo usunięcie niepustego katalogu może się nie powieść, jeśli usunięcie podkatalogu lub pliku w nim jeszcze się nie zakończyło do czasu próby usunięcia katalogu nadrzędnego.
Rzadziej: odtwarzanie usuniętego katalogu natychmiast po usunięciu może się nie powieść, ponieważ usunięcie mogło nie zostać jeszcze ukończone do czasu próby odtworzenia.
Problem nie dotyczy tylko PowerShell użytkownika
Remove-Item
, ale równieżcmd.exe
„srd /s
jak .NET na[System.IO.Directory]::Delete()
:Począwszy od Windows PowerShell v5.1 / PowerShell Core 6.2.0-Preview.1 /
cmd.exe
10.0.17134.407 / .NET Framework 4.7.03056, .NET Core 2.1, ani nieRemove-Item
, anird /s
nie[System.IO.Directory]::Delete()
działają niezawodnie , ponieważ nie uwzględniają asynchronicznego zachowanie funkcji usuwania plików / katalogów Windows API :cmd.exe
Zgłoszenie błęduAby uzyskać niestandardową funkcję programu PowerShell, która zapewnia niezawodne synchroniczne obejście , zobacz tę odpowiedź SO .
źródło
while($true) { if ( (Remove-Item [...] *>&1) -ne $null) { Start-Sleep 0.5 } else { break } }
Obecna odpowiedź nie spowoduje usunięcia katalogu, tylko jego dzieci. Ponadto będzie miał problemy z zagnieżdżonymi katalogami, ponieważ ponownie będzie próbował usunąć katalog przed jego zawartością. Napisałem coś, aby usunąć pliki we właściwej kolejności, nadal miałbym ten sam problem, chociaż czasami katalog nadal byłby w pobliżu.
Więc teraz używam czegoś, co złapie wyjątek, poczekaj i ponów próbę (3 razy):
Na razie używam tego:
źródło
Aby usunąć katalog i jego zawartość, należy wykonać dwa kroki. Najpierw usuń zawartość, a następnie sam folder. Korzystając z obejścia wadliwego rekurencyjnego elementu usuwającego, rozwiązanie wyglądałoby następująco:
W ten sposób możesz również usunąć katalog nadrzędny.
źródło
Remove-Item
Polecenia swoje rurociągi do ma ten sam problem, który pierwotnie podane. Może się potknąć o element katalogu, który nie jest pusty w ten sam sposób.Remove-Item -Recurse
nadal jest zaangażowane. Problem podstawowy nadal występuje w Windows PowerShell v5.1 / PowerShell Core 6.2.0-Preview.1 - zobacz ten raport o błędzie .Boże Wiele odpowiedzi. Szczerze wolę ten od nich wszystkich. Jest bardzo prosty, kompletny, czytelny i działa na dowolnym komputerze z systemem Windows. Wykorzystuje (niezawodną) funkcję kasowania rekurencyjnego .NET, a jeśli z jakiegoś powodu zawiedzie, generuje odpowiedni wyjątek, który można obsłużyć za pomocą bloku try / catch.
Należy pamiętać, że
Resolve-Path
wiersz jest ważny, ponieważ .NET nie rozpoznaje bieżącego katalogu podczas rozwiązywania względnych ścieżek plików. To jedyna myśl, o której mogę myśleć.źródło
Oto co mam do pracy:
Ten pierwszy wiersz usuwa wszystkie pliki z drzewa. Drugi usuwa wszystkie foldery, w tym górny.
źródło
Remove-Item -Recurse
nadal jest zaangażowane. Problem podstawowy nadal występuje w Windows PowerShell v5.1 / PowerShell Core 6.2.0-Preview.1 - zobacz ten raport o błędzie .Przejmij na własność pliki / katalogi za pomocą Takeown.exe, a następnie usuń
https://learn-powershell.net/2014/06/24/changing-ownership-of-file-or-folder-using-powershell/
źródło
Miałem ten problem z katalogiem, którego nie można usunąć. Odkryłem, że jeden z podfolderów był uszkodzony i kiedy próbowałem przenieść lub zmienić nazwę tego dziecięcego katalogu, dostałem komunikat o błędzie informujący o tym, że go brakuje. Próbowałem użyć rm -Force i dostałem ten sam błąd co ty.
Dla mnie zadziałało skompresowanie katalogu nadrzędnego za pomocą 7-zip z zaznaczoną opcją „Usuń pliki po kompresji”. Po skompresowaniu udało mi się usunąć plik zip.
źródło