De alguma forma, uma de nossas antigas caixas do Server 2008 (não o R2) desenvolveu uma pasta aparentemente infinitamente recorrente. Isso está atrapalhando nossos backups, pois o agente de backup tenta recuar para a pasta e nunca mais retorna.
A estrutura da pasta se parece com:
C:\Storage\Folder1
C:\Storage\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1
C:\Storage\Folder1\Folder1\Folder1\Folder1
... e assim por diante. É como um daqueles sets de Mandelbrot com os quais brincávamos nos anos 90.
Eu tentei:
- Excluindo-o do Explorer. Sim, sou otimista.
RMDIR C:\Storage\Folder1 /Q/S
- isso retornaThe directory is not empty
ROBOCOPY C:\temp\EmptyDirectory C:\Storage\Folder1 /PURGE
- ele percorre as pastas por alguns minutos antes de o robocopy.exe travar.
Alguém pode sugerir uma maneira de eliminar esta pasta definitivamente?
/MIR
:ROBOCOPY /MIR C:\temp\EmptyDirectory C:\Storage\Folder1
também pode valer a pena dar umachkdsk
risadinha./MIR
pareceu durar mais tempo, mas acabou sendo bombardeado ("a robocopia parou de funcionar"). Estou com um pouco de medo de fazer umchkdsk
; este é um servidor muito velho e eu estou preocupado que este problema é indicativo de problemas maiores do sistema de arquivos ...find
fazer uma remoção profunda do primeiro diretório:find Storage/Folder1 -depth -exec rmdir {} \;
Respostas:
Obrigado a todos pelos conselhos úteis.
Indo bem ao território do StackOverflow, resolvi o problema usando este trecho de código C #. Ele usa a biblioteca Delimon.Win32.IO que aborda especificamente problemas ao acessar caminhos de arquivos longos.
Caso isso possa ajudar alguém, aqui está o código - ele superou os ~ 1600 níveis de recursão com os quais eu estava de alguma forma preso e levou cerca de 20 minutos para removê-los.
fonte
.Delete
(em vez daSystem.IO
versão normal ), e embora não tenha lançado uma exceção, não pareceu fazer nada. Certamente a recursão usando o método acima levou séculos e.Delete
só mastigou as coisas por 5 a 10 segundos. Talvez tenha quebrado alguns diretórios e depois tenha desistido?Pode ser um ponto de junção recursivo. Uma coisa dessas pode ser criada com
junction
um utilitário de arquivo e disco da Sysinternals .E agora você pode descer sem parar c: \ Hello \ Hello \ Hello .... (até MAX_PATH ser atingido, 260 caracteres para a maioria dos comandos, mas 32.767 caracteres para algumas funções da API do Windows).
Uma lista de diretórios mostra que é uma junção:
Para excluir, use o utilitário de junção:
fonte
DIR
apenas me mostra simples diretórios ole - nenhum sinal de cruzamentos Receiojunction -s C:\Storage\Folder1
?No reparse points found
:( #dir /a
para ver '<JUNCTION>' sem especificar o nome específico.Não é uma resposta, mas não tenho representante suficiente para comentar.
Certa vez, corrigi esse problema em um enorme disco de 500 MB FAT16 em um sistema MS-DOS. Eu usei a depuração do DOS para despejar e analisar manualmente a tabela de diretórios. Em seguida, virei um pouco para marcar o diretório recursivo como excluído. Minha cópia do Dettman e Wyatt 'DOS Programmers' Reference 'me mostrou o caminho.
Ainda estou despreocupadamente orgulhoso disso. Eu ficaria surpreso e aterrorizado se houver alguma ferramenta de uso geral que tenha tanto poder sobre os volumes FAT32 ou NTFS. A vida era mais simples naquela época.
fonte
Java também pode lidar com caminhos de arquivo longos. E pode fazê-lo muito mais rápido também. Esse código (que copiei da documentação da API Java) excluirá uma estrutura de diretórios profundos de 1600 níveis em cerca de 1 segundo (no Windows 7, Java 8.0) e sem risco de estouro de pilha, pois na verdade não usa recursão.
fonte
Você não precisa de nomes de caminho longos se
chdir
entrar no diretório e usar apenas caminhos relativos pararmdir
.Ou, se você tiver um shell POSIX instalado, ou portá-lo para o equivalente do DOS:
(Usar uma variável shell para rastrear onde você a renomeou para a condição de loop é a outra alternativa para desenrolar o loop como eu fiz lá.)
Isso evita a sobrecarga da CPU da solução da KenD, que força o sistema operacional a atravessar a árvore do topo para o
n
quinto nível toda vez que um novo nível é adicionado, verificando permissões etc. Por isso, possuisum(1, n) = n * (n-1) / 2 = O(n^2)
complexidade de tempo. As soluções que separam um pedaço do início da cadeia devem serO(n)
, a menos que o Windows precise percorrer uma árvore ao renomear seu diretório pai. (Linux / Unix não.) Soluções quechdir
vãochdir
até a parte inferior da árvore e usam caminhos relativos a partir daí, removendo diretórios à medida que eles fazem backup, também devem serO(n)
, assumindo que o sistema operacional não precise verificar todas as suas diretórios-pai a cada chamada do sistema, quando você faz coisas enquanto está em CD em algum lugar.find Folder1 -depth -execdir rmdir {} +
executará o rmdir enquanto estiver em CD no diretório mais profundo. Ou, na verdade, a-delete
opção do find funciona em diretórios e implica-depth
. Então,find Folder1 -delete
deve fazer exatamente a mesma coisa, mas mais rápido. Sim, a localização do GNU no Linux desce, varrendo um diretório, colocando CD em subdiretórios com caminhos relativos e, em seguida,rmdir
com um caminho relativochdir("..")
. Ele não verifica novamente os diretórios enquanto ascende, portanto consumiriaO(n)
RAM.Isso foi realmente uma aproximação:
strace
mostra que realmente utilizaunlinkat(AT_FDCWD, "tmp", AT_REMOVEDIR)
,open("..", O_DIRECTORY|...)
efchdir(the fd from opening the directory)
, com um monte defstat
chamadas misturados também. Mas o efeito é o mesmo se a árvore de diretórios não for modificada enquanto a localização estiver em execução.edit: Tentei fazer isso no GNU / Linux (Ubuntu 14.10, em uma CPU Core2Duo de primeira geração a 2,4 GHz, em um sistema de arquivos XFS em uma unidade WD 2.5TB Green Power (WD25EZRS)).
(mkdir -p cria um diretório e quaisquer componentes de caminho ausentes).
Sim, realmente 0,05 segundos para 2k rmdir ops. O xfs é muito bom em agrupar operações de metadados juntos no diário, uma vez que eles corrigiam operações de metadados sendo lentas como há 10 anos.
No ext4, a criação levou 0m0.279s, a exclusão com localização ainda levou 0m0.074s.
fonte
Corri para o mesmo problema com uma confusão de pastas com mais de 5000 diretórios que algum aplicativo Java fazia e escrevi um programa que o ajudará a remover esta pasta. Todo o código fonte está neste link:
https://imanolbarba.net/gitlab/imanol/DiREKT
Ele removeu tudo depois de um tempo, mas conseguiu fazer o trabalho, espero que ajude as pessoas que (como eu) enfrentam o mesmo problema frustrante
fonte
Eu também tive isso, em um sistema Windows 10 independente. C: \ Usuário \ Nome \ Repita \ Repita \ Repita \ Repita \ Repita \ Repita \ Repita aparentemente até o infinito.
Eu poderia navegar usando o Windows ou o Prompt de Comando até o 50º e não mais. Não consegui excluí-lo ou clicar nele, etc.
C é a minha linguagem e, por fim, escrevi um programa com um loop de chamadas do sistema, que se repetem até que falhem. Você pode fazer isso em qualquer idioma, mesmo em lotes DOS. Criei um diretório chamado tmp e movi Repeat \ Repeat para ele, excluí a pasta Repeat agora vazia e movi tmp \ Repeat novamente para a pasta atual. Repetidamente!
O ChkSystem apenas executa uma chamada system () e verifica o valor de retorno, parando se falhar.
Importante, ele falhou várias vezes. Pensei que talvez meu programa não estivesse funcionando ou que fosse infinitamente longo, afinal. No entanto, eu já tive isso antes com chamadas do sistema, com coisas não sincronizando, então apenas executei o programa novamente e ele continuou de onde parou, portanto, não pense imediatamente que seu programa não está funcionando. Então, no total, depois de executá-lo cerca de 20 vezes, ele limpou todos eles. No total, havia cerca de 1280 pastas de profundidade originalmente. Não faço ideia do que causou isso. Louco.
fonte