user340956 był boleśnie blisko rozwiązania, ale wiesz, co mówią o bliskości…
Aby było jasne, rd /s /q c:\foobar
kasuje katalog docelowy oprócz jego zawartości, ale nie zawsze chcesz usunąć sam katalog, czasami po prostu chcesz usunąć jego zawartość i zostawić go w spokoju. Polecenie deltree
mogłoby to zrobić, ale Micrsoft w swojej nieskończonej “mądrości” usunął to polecenie i nie przeportował go do systemu Windows.
Oto rozwiązanie, które działa bez uciekania się do narzędzi innych firm. Prawdopodobnie jest ono tak proste i efektywne, jak to tylko możliwe przy użyciu skryptu z linią poleceń, zamiast pisania prawdziwego pliku wykonywalnego. Nie ustawia on żadnych zmiennych środowiskowych i nie używa żadnych pętli. Jest także tak bezpieczny, jak to tylko możliwe, z możliwością sprawdzania błędów wszędzie tam, gdzie to możliwe, a także tak przyjazny dla użytkownika, jak to tylko możliwe, z wbudowanymi dokumentami.
dt.bat
(lub dt.cmd
dla dzieci; cokolwiek, jestem stary, używam .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
Oto jak to działa:
- Sprawdza, czy argument linii poleceń został przekazany, i drukuje informacje o użyciu, a jeśli nie, to kończy pracę.
- Używa
pushd
do zapisania aktualnego katalogu, a następnie przełącza się do katalogu docelowego, przekierowując wszelkie błędy do nul
w celu uzyskania czystszego doświadczenia z linią poleceń (i czystszych logów).
- Sprawdza, czy aktualny katalog jest teraz taki sam, jak katalog docelowy, i wypisuje komunikat o błędzie i kończy pracę, jeśli nie jest. Pozwala to uniknąć przypadkowego skasowania zawartości poprzedniego katalogu, jeśli polecenie
pushd
nie powiodło się (np, Przekazywanie nieprawidłowego katalogu, błąd dostępu, itp.)
- To sprawdzenie nie uwzględnia wielkości liter, więc jest usualnie bezpieczne w systemie Windows, ale nie jest przeznaczone dla systemów plików wrażliwych na wielkość liter, takich jak te używane przez systemy *nix, nawet pod Windows.
- Nie działa w przypadku nazw plików krótkich (np.
C:\Users\Bob Bobson\foobar
nie będzie postrzegane jako takie same jak C:\Users\BobBob~1\foobar
, nawet jeśli są one rzeczywiście). Niewielką niedogodnością jest konieczność używania nie-krótkich nazw plików, ale jest to bardziej bezpieczne niż przykre, zwłaszcza, że SFN-y nie są całkowicie niezawodne lub zawsze przewidywalne (a nawet mogą być całkowicie wyłączone).
- Następnie używa
rd
do usunięcia katalogu docelowego i całej jego zawartości, przekierowując wszelkie błędy (które powinny być przynajmniej jedno dla samego katalogu) do nul
. Kilka uwag na ten temat:
- Ponieważ katalog docelowy jest katalogiem bieżącym, system ma do niego otwarty uchwyt do plików, a więc nie może go faktycznie usunąć, więc pozostaje taki, jaki jest, co jest pożądanym zachowaniem.
- Ponieważ nie próbuje usunąć katalogu docelowego, dopóki jego zawartość nie zostanie usunięta, powinien być teraz pusty (poza tym, co również ma otwarte uchwyty do plików).
- Na koniec, używa
popd
do powrotu do poprzedniego katalogu i kończy pracę skryptu.
(Jeśli chcesz, możesz skrypt skomentować powyższy opis używając rem
lub ::
).