user340956 estava dolorosamente perto da solução, mas sabe o que dizem sobre fechar…
Para ser claro, rd /s /q c:\foobar
apaga o directório de destino para além do seu conteúdo, mas nem sempre quer apagar o directório em si, por vezes só quer apagar o seu conteúdo e deixar o directório em paz. O comando deltree
podia fazer isto, mas o Micrsoft, na sua infinita “sabedoria” removeu o comando e não o portou para o Windows.
Aqui está uma solução que funciona sem recorrer a ferramentas de terceiros. É provavelmente tão simples e eficiente quanto possível com um script de linha de comando, em vez de escrever um executável real. Não define nenhuma variável de ambiente e não utiliza nenhum loops. É também tão seguro quanto possível, com verificação de erros em todo o lado possível, e também tão fácil de usar quanto possível, com documentos integrados.
dt.bat
(ou dt.cmd
para as crianças; o que quer que seja, eu sou velho, eu uso .bat
):
:: dt is a Windows-compatible version of the deltree command
:: Posted to SuperUser by Synetech: https://superuser.com/a/1526232/3279
@echo off
goto start
:start
if ["%~1"]==[""] goto usage
pushd "%~1" 2>nul
if /i not ["%cd%"]==["%~1"] goto wrongdir
rd /s /q "%~1" 2>nul
popd
goto :eof
:usage
echo Delete all of the contents of a directory
echo.
echo ^> %0 DIR
echo.
echo %0 is a substitute for deltree, it recursively deletes the contents
echo (files and folders) of a directory, but not the directory itself
echo.
echo DIR is the directory whose contents are to be deleted
goto :eof
:wrongdir
echo Could not change to the target directory. Invalid directory? Access denied?
goto :eof
Aqui está como funciona:
- Verifica se um argumento de linha de comando foi passado, e imprime informação de utilização e sai se não for.
- Utiliza os
pushd
para guardar o directório actual, depois muda para o directório de destino, redireccionando quaisquer erros para nul
para uma experiência de linha de comando mais limpa (e registos mais limpos).
- Verifica se o directório actual é agora o mesmo que o directório de destino, imprime uma mensagem de erro e sai do directório se não for. Isto evita apagar acidentalmente o conteúdo do directório anterior se o comando
pushd
falhar (por exemplo, o comando C:\Users\Bob Bobson\foobar
não é compatível com o directório de destino), passando um directório inválido, erro de acesso, etc.)
- Esta verificação é insensível a maiúsculas e minúsculas, por isso é usualmente seguro no Windows, mas não é para sistemas de ficheiros sensíveis a maiúsculas e minúsculas como os utilizados pelos sistemas *nix, mesmo sob o Windows.
- Não funciona com nomes curtos (por exemplo,
C:\Users\BobBob~1\foobar
não será visto como sendo o mesmo que rd
, mesmo que realmente o seja). É um pequeno inconveniente ter de usar o nome de ficheiro não curto, mas é melhor prevenir do que remediar, especialmente porque os SFNs não são completamente fiáveis ou sempre previsíveis (e podem até ser totalmente desactivados).
- Depois usa o
nul
para apagar o directório de destino e todo o seu conteúdo, redireccionando quaisquer erros (que devem existir pelo menos um para o próprio directório) para o popd
. Algumas notas sobre isto:
- Porque o directório de destino é o directório actual, o sistema tem um ficheiro aberto e, portanto, não o pode apagar, pelo que permanece como está, que é o comportamento desejado.
- Porque só tenta remover o directório de destino depois de o seu conteúdo ter sido removido, deve agora estar vazio (para além de tudo o que também tenha pegas de ficheiro abertas).
- Finalmente, utiliza o
rem
para voltar ao directório anterior e terminar o script.
(Se quiser, pode comentar o script com as descrições acima usando ::
ou &007.)