Estou tentando excluir um diretório recursivamente com rm -Force -Recurse somedirectory
, recebo vários erros "O diretório não está vazio". Se eu tentar novamente o mesmo comando , ele será bem-sucedido.
Exemplo:
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>
Claro, isso não acontece sempre . Além disso, isso não acontece apenas com _svn
diretórios, e eu não tenho um cache TortoiseSVN ou algo assim, então nada está bloqueando o diretório.
Alguma ideia?
help Remove-Item
diz:e
e propõe esta alternativa como exemplo:
Então você deve canalizar
get-childitem -recurse
emremove-item
.@JamesCW: O problema ainda existe no PowerShell 4.0
Eu tentei outra solução alternativa e funcionou: use cmd.exe:
Atualização : Começando com (pelo menos) Windows 10 versão 20H2 (não sei qual versão do Windows Server e build que corresponde a; execute
winver.exe
para verificar sua versão e build), aDeleteFile
função da API do Windows agora exibe comportamento síncrono , que resolve implicitamente o problemas com PowerShellRemove-Item
e .NET'sSystem.IO.File.Delete
/System.IO.Directory.Delete
(mas, curiosamente, não comcmd.exe
'srd /s
).As respostas existentes atenuam o problema, para que ocorra com menos frequência, mas não abordam a causa raiz , razão pela qual ainda podem ocorrer falhas .
Remove-Item -Recurse
é inesperadamente assíncrono , principalmente porque os métodos da API do Windows para remoção de arquivos e diretórios são inerentemente assíncronos eRemove-Item
não levam em conta isso.Isso se manifesta de forma intermitente e imprevisível de duas maneiras:
Seu caso: A remoção de um diretório não vazio em si pode falhar, se a remoção de um subdiretório ou arquivo nele ainda não tiver sido concluída no momento em que for feita uma tentativa de remover o diretório pai.
Menos comum: A recriação de um diretório removido imediatamente após a remoção pode falhar, porque a remoção pode ainda não ter sido concluída no momento em que a recriação é tentada.
O problema não afeta apenas o PowerShell
Remove-Item
, mas tambémcmd.exe
ord /s
.NET[System.IO.Directory]::Delete()
:A partir do 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, nemRemove-Item
, nemrd /s
, nem[System.IO.Directory]::Delete()
funcionam de forma confiável , porque eles não contabilizam o assíncrono comportamento das funções de remoção de arquivo/diretório da API do Windows :cmd.exe
relatório de erroPara uma função personalizada do PowerShell que fornece uma solução síncrona confiável , consulte esta resposta SO .
ETA 20181217: PSVersion 4.0 e posterior ainda falhará em algumas circunstâncias, veja resposta alternativa de Mehrdad Mirreza e relatório de bug arquivado por mklement
mklement fornece uma solução de prova de conceito nesta resposta SO , pois o bug está aguardando uma correção oficial
A nova versão de
PowerShell
(PSVersion 4.0
) resolveu esse problema inteiramente eRemove-Item "targetdirectory" -Recurse -Force
funciona sem problemas de tempo.Você pode verificar sua versão executando
$PSVersiontable
de dentro do ISE ou doPowerShell
prompt. 4.0 é a versão que acompanhaWindows 8.1
eServer 2012 R2
, e também pode ser instalada em versões anteriores do Windows.Poxa. Muitas respostas. Sinceramente, prefiro este a todos. É super simples, completo, legível e funciona em qualquer máquina Windows. Ele usa a funcionalidade de exclusão recursiva (confiável) do .NET e, se falhar por algum motivo, lança uma exceção adequada que pode ser tratada com um bloco try/catch.
Observe que a
Resolve-Path
linha é importante porque o .NET não reconhece seu diretório atual ao resolver caminhos de arquivos relativos. Essa é a única pegadinha que consigo pensar.A resposta atual não excluirá um diretório, apenas seus filhos. Além disso, ele terá problemas com diretórios aninhados, pois novamente tentará excluir um diretório antes de seu conteúdo. Eu escrevi algo para excluir os arquivos na ordem correta, ainda teria o mesmo problema, embora às vezes o diretório ainda estivesse por aí depois.
Então, agora eu uso algo que irá capturar a exceção, esperar e tentar novamente (3 vezes):
Por enquanto estou usando isso:
Para excluir o diretório e seu conteúdo, são necessários dois passos. Primeiro exclua o conteúdo, depois a própria pasta. Usando a solução alternativa para o item de remoção recursiva com defeito, a solução ficaria assim:
Dessa forma, você também pode remover o diretório pai.
Isto é o que eu tenho trabalhando:
Esta primeira linha exclui todos os arquivos da árvore. O segundo exclui todas as pastas, incluindo a parte superior.
Assuma a propriedade dos arquivos / diretórios primeiro usando Takeown.exe e exclua
https://learn-powershell.net/2014/06/24/change-ownership-of-file-or-folder-using-powershell/
Eu tive esse problema com um diretório que não iria excluir. Descobri que uma das subpastas estava corrompida e, quando tentei mover ou renomear esse diretório filho, recebi uma mensagem de erro dizendo que algo estava faltando. Eu tentei usar rm -Force e recebi o mesmo erro que você.
O que funcionou para mim foi compactar o diretório pai usando 7-zip com a opção "Excluir arquivos após compactação" marcada. Depois de compactado, consegui excluir o arquivo zip.